Banco de Dados - MySQL
Apache Cassandra NoSQL, uma tecnologia emergente
Disponibilizo neste documento, os procedimentos necessário (e sem mistério) para instalar o Apache Cassandra. Sendo assim, uma oportunidade para conhecer um pouco desta tecnologia emergente.
por Alessandro de Oliveira FariaIntrodução
Jogo rápido, download e instalação
Desenvolvido inicialmente pelo Facebook como open source em 2008, cujo objetivo foi ampliar o universo de instalação MySQL, o Cassandra exerce com excelência a função de repositório de dados. Leve e desenvolvido na plataforma Java, ele não apresenta a sobrecarga de recurso do banco de dados convencionais. Atualmente o projeto é baseado na tecnologia emergente NoSQL e encontra-se incubado pela Fundação Apache.
Com poucos minutos de pesquisa na internet, é possível encontrar testes realizados por diversos segmentos demonstrando confiabilidade, escalabilidade e fácil gerenciamento. Atualmente o Twitter apresenta uma massa crítica e pesada baseada no seu monstruoso crescimento atrelado a escala temporal, sendo assim, este cenário é um excelente "caso de sucesso" para o Apache Cassandra. Instalei o projeto Apache Cassandra e veremos na próxima página, passo-a-passo como fazê-lo sem trauma algum. NoSQL conta com sua maior aplicação atual: 100 terabytes de dados e 150 servidores (uma base consideravelmente grande). Diversas APIs de acesso proporcionam o seu uso de forma muito simples (Ruby, Perl, Scala, Python, PHP e Java).
O Digg usa o Cassandra, o Facebook (desenvolvedor original) e agora o Twitter. Isto demonstra que a desnormalização de dados não é um problema onde geralmente leva-se em conta ao custo do espaço em disco. O vasto campo do NoSQL está gerando grandes interesses, e as sua técnicas estão colocando em evidências os bancos de dados NoSQL.
O texto a seguir foi extraído do post do blog globalcoder e ilustra bem o atual polêmico cenário:
"Escalabilidade é um tema bastante complexo e armazenamento e processamento de grandes volumes de dados são focos de pesquisas que estão bem aquecidas hoje em dia. Um dos mais ativos movimentos nesta linha está tomando forma, encorpando e sendo batizado. Chama-se NoSQL. Em um livro recém lançado intitulado "Hadoop: The Definitive Guide" (escrito por Tom White) há uma passagem digna de nota (em uma tradução livre):
Este é o resumo de como a história acerca de escalabilidade no uso de um banco de dados relacional se desenrola. A seguinte lista assume uma aplicação de sucesso, de demanda crescente.
Lançamento ao público inicial:
Cópia da instância MySQL de desenvolvimento para o ambiente de produção, compartilhado e remoto, tendo um esquema de dados bem definido.
A aplicação se torna mais popular; requisições demasiadas de leitura atingindo o banco de dados:
Adiciona-se "memcached" ao sistema para que as requisições mais comuns se mantenham em memória. As leituras ao banco de dados não são mais estritamente ACID; dados armazenados em memória devem ser invalidados por algum mecanismo.
A aplicação continua com crescente demanda; requisições demasiadas de escrita atingindo o banco de dados:
Escala-se verticalmente o MySQL através da atualização de hardware do servidor com 16 núcleos, 128 GB de RAM e bancos de discos rígidos com 15000 RPMs. Oneroso.
Novos recursos implementados no sistema aumentam a complexidade das consultas SQL; agora temos muitos "joins":
Desnormalização dos dados para reduzir "joins" (isto não é o que eles ensinam na escola para DBA).
Demanda da aplicação cresce e derruba o servidor; tudo está muito lento:
Para-se com qualquer processamento no lado do servidor.
Algumas consultas ainda estão lentas:
Cria-se periodicamente "views" materializadas das consultas mais complexas, tenta-se eliminar "joins" na maioria dos casos.
Leituras estão aceitáveis mas escritas estão cada vez mais lentas e lentas:
Elimina-se índices secundários e "triggers"! Sem índices? ...
Quantos de nós estamos envolvidos com sistemas que estão nesta rota? Será mesmo que nossas aplicações nunca atingirão tais níveis?"
Texto extraído de: http://blog.globalcode.com.br/
Bom, agora chega de blá, blá, blá e partiremos para o que realmente interessa, a mão na massa...
Com poucos minutos de pesquisa na internet, é possível encontrar testes realizados por diversos segmentos demonstrando confiabilidade, escalabilidade e fácil gerenciamento. Atualmente o Twitter apresenta uma massa crítica e pesada baseada no seu monstruoso crescimento atrelado a escala temporal, sendo assim, este cenário é um excelente "caso de sucesso" para o Apache Cassandra. Instalei o projeto Apache Cassandra e veremos na próxima página, passo-a-passo como fazê-lo sem trauma algum. NoSQL conta com sua maior aplicação atual: 100 terabytes de dados e 150 servidores (uma base consideravelmente grande). Diversas APIs de acesso proporcionam o seu uso de forma muito simples (Ruby, Perl, Scala, Python, PHP e Java).
O Digg usa o Cassandra, o Facebook (desenvolvedor original) e agora o Twitter. Isto demonstra que a desnormalização de dados não é um problema onde geralmente leva-se em conta ao custo do espaço em disco. O vasto campo do NoSQL está gerando grandes interesses, e as sua técnicas estão colocando em evidências os bancos de dados NoSQL.
O texto a seguir foi extraído do post do blog globalcoder e ilustra bem o atual polêmico cenário:
"Escalabilidade é um tema bastante complexo e armazenamento e processamento de grandes volumes de dados são focos de pesquisas que estão bem aquecidas hoje em dia. Um dos mais ativos movimentos nesta linha está tomando forma, encorpando e sendo batizado. Chama-se NoSQL. Em um livro recém lançado intitulado "Hadoop: The Definitive Guide" (escrito por Tom White) há uma passagem digna de nota (em uma tradução livre):
Este é o resumo de como a história acerca de escalabilidade no uso de um banco de dados relacional se desenrola. A seguinte lista assume uma aplicação de sucesso, de demanda crescente.
Lançamento ao público inicial:
Cópia da instância MySQL de desenvolvimento para o ambiente de produção, compartilhado e remoto, tendo um esquema de dados bem definido.
A aplicação se torna mais popular; requisições demasiadas de leitura atingindo o banco de dados:
Adiciona-se "memcached" ao sistema para que as requisições mais comuns se mantenham em memória. As leituras ao banco de dados não são mais estritamente ACID; dados armazenados em memória devem ser invalidados por algum mecanismo.
A aplicação continua com crescente demanda; requisições demasiadas de escrita atingindo o banco de dados:
Escala-se verticalmente o MySQL através da atualização de hardware do servidor com 16 núcleos, 128 GB de RAM e bancos de discos rígidos com 15000 RPMs. Oneroso.
Novos recursos implementados no sistema aumentam a complexidade das consultas SQL; agora temos muitos "joins":
Desnormalização dos dados para reduzir "joins" (isto não é o que eles ensinam na escola para DBA).
Demanda da aplicação cresce e derruba o servidor; tudo está muito lento:
Para-se com qualquer processamento no lado do servidor.
Algumas consultas ainda estão lentas:
Cria-se periodicamente "views" materializadas das consultas mais complexas, tenta-se eliminar "joins" na maioria dos casos.
Leituras estão aceitáveis mas escritas estão cada vez mais lentas e lentas:
Elimina-se índices secundários e "triggers"! Sem índices? ...
Quantos de nós estamos envolvidos com sistemas que estão nesta rota? Será mesmo que nossas aplicações nunca atingirão tais níveis?"
Texto extraído de: http://blog.globalcode.com.br/
Bom, agora chega de blá, blá, blá e partiremos para o que realmente interessa, a mão na massa...
Jogo rápido, download e instalação
Em primeiro lugar efetue o download em:
# wget http://linorg.usp.br/apache/cassandra/0.5.1/apache-cassandra-0.5.1-bin.tar.gz
Descompacte o pacote com o tradicional comando "tar -zxvf" e configure a variável ambiental CASSANDRA_HOME:
# cd /opt
# tar -zxvf apache-cassandra-0.5.1-bin.tar.gz
# export CASSANDRA_HOME=/opt/apache-cassandra-0.5.1
Modifique o arquivo storage-conf.xml conforme as suas necessidades e crie as pastas:
# cd /opt/apache-cassandra-0.5.1/conf/
# vi storage-conf.xml
Crie os diretórios especificados no arquivo storage-conf.xml mencionado anteriormente.
# mkdir -p /var/lib/cassandra/commitlog
# mkdir /var/lib/cassandra/data
# mkdir /var/lib/cassandra/callouts
# mkdir /var/lib/cassandra/staging
# mkdir -p /var/log/cassandra
# mkdir -p /var/lib/cassandra
ATENÇÃO:
Se você optou baixar o código fonte, basta utilizar o comando abaixo para compilar o pacote:
# ant ivy-retrieve
Pronto, inicie o serviço Cassandra executando o script "cassandra" na pasta bin seguido do parâmetro -f:
# bin/cassandra -f
Para executar o cliente, entre na pasta /opt/apache-cassandra-0.5.1/bin/ e execute o comando "cassandra-cli" seguido no IP do servidor e a porta. No nosso caso, utilizaremos o valores default (localhost e porta 9160).
# cd /opt/apache-cassandra-0.5.1/bin/
# ./cassandra-cli --host localhost --port 9160
Connected to localhost/9160
Welcome to cassandra CLI.
Type "help" or "?" for help. Type "quit" or "exit" to quit.
Cassandra>
Agora no console cliente do Cassandra, utilize os comandos do exemplo abaixo para inserir uma chave:
cassandra> set Keyspace1.Standard1["cabelo"]["first"] = "Alessandro"
Value inserted.
cassandra> set Keyspace1.Standard1["cabelo"]["last"] = "Faria"
Value inserted.
cassandra> set Keyspace1.Standard1["cabelo"]["age"] = "38"
Value inserted.
Consultando a chave inclusa anteriormente:
cassandra> get Keyspace1.Standard1["cabelo"]
=> (column=6c617374, value=Faria, timestamp=1267416876445)
=> (column=6669727374, value=Alessandro, timestamp=1267416865908)
=> (column=616765, value=38, timestamp=1267416894415)
Returned 3 results.
Excluindo a chave adicionada anteriormente:
cassandra> del Keyspace1.Standard1["cabelo"]
row removed.
E o desenvolvimento? Para os desenvolvedores, sugiro o projeto Cassandra Java Client. A seguir uma receita de bolo (da página oficial) de como efetuar o download e testá-lo:
$ svn checkout https://cassandra-java-client.googlecode.com/svn/trunk/ cassandra-java-client
$ cd cassandra-java-client
$ mvn install
Abaixo um código exemplo extraível da própria página do projeto:
Acredito que este documento permita alavancar o interesse para outros projetos com a tecnologia NoSQL. Como sempre menciono: Colaborar atrai amigos, competir atrai inimigos... Sobre o autor: http://www.netitec.com.br/alessandro
# wget http://linorg.usp.br/apache/cassandra/0.5.1/apache-cassandra-0.5.1-bin.tar.gz
Descompacte o pacote com o tradicional comando "tar -zxvf" e configure a variável ambiental CASSANDRA_HOME:
# cd /opt
# tar -zxvf apache-cassandra-0.5.1-bin.tar.gz
# export CASSANDRA_HOME=/opt/apache-cassandra-0.5.1
Modifique o arquivo storage-conf.xml conforme as suas necessidades e crie as pastas:
# cd /opt/apache-cassandra-0.5.1/conf/
# vi storage-conf.xml
Crie os diretórios especificados no arquivo storage-conf.xml mencionado anteriormente.
# mkdir -p /var/lib/cassandra/commitlog
# mkdir /var/lib/cassandra/data
# mkdir /var/lib/cassandra/callouts
# mkdir /var/lib/cassandra/staging
# mkdir -p /var/log/cassandra
# mkdir -p /var/lib/cassandra
ATENÇÃO:
Se você optou baixar o código fonte, basta utilizar o comando abaixo para compilar o pacote:
# ant ivy-retrieve
Pronto, inicie o serviço Cassandra executando o script "cassandra" na pasta bin seguido do parâmetro -f:
# bin/cassandra -f
Para executar o cliente, entre na pasta /opt/apache-cassandra-0.5.1/bin/ e execute o comando "cassandra-cli" seguido no IP do servidor e a porta. No nosso caso, utilizaremos o valores default (localhost e porta 9160).
# cd /opt/apache-cassandra-0.5.1/bin/
# ./cassandra-cli --host localhost --port 9160
Connected to localhost/9160
Welcome to cassandra CLI.
Type "help" or "?" for help. Type "quit" or "exit" to quit.
Cassandra>
Agora no console cliente do Cassandra, utilize os comandos do exemplo abaixo para inserir uma chave:
cassandra> set Keyspace1.Standard1["cabelo"]["first"] = "Alessandro"
Value inserted.
cassandra> set Keyspace1.Standard1["cabelo"]["last"] = "Faria"
Value inserted.
cassandra> set Keyspace1.Standard1["cabelo"]["age"] = "38"
Value inserted.
Consultando a chave inclusa anteriormente:
cassandra> get Keyspace1.Standard1["cabelo"]
=> (column=6c617374, value=Faria, timestamp=1267416876445)
=> (column=6669727374, value=Alessandro, timestamp=1267416865908)
=> (column=616765, value=38, timestamp=1267416894415)
Returned 3 results.
Excluindo a chave adicionada anteriormente:
cassandra> del Keyspace1.Standard1["cabelo"]
row removed.
E o desenvolvimento? Para os desenvolvedores, sugiro o projeto Cassandra Java Client. A seguir uma receita de bolo (da página oficial) de como efetuar o download e testá-lo:
$ svn checkout https://cassandra-java-client.googlecode.com/svn/trunk/ cassandra-java-client
$ cd cassandra-java-client
$ mvn install
Abaixo um código exemplo extraível da própria página do projeto:
CassandraClient cl = pool.getClient() ;
KeySpace ks = cl.getKeySpace("Keyspace1") ;
// insert value
ColumnPath cp = new ColumnPath("Standard1" , null, "testInsertAndGetAndRemove".getBytes("utf-8"));
for(int i = 0 ; i < 100 ; i++){
ks.insert("testInsertAndGetAndRemove_"+i, cp , ("testInsertAndGetAndRemove_value_"+i).getBytes("utf-8"));
}
//get value
for(int i = 0 ; i < 100 ; i++){
Column col = ks.getColumn("testInsertAndGetAndRemove_"+i, cp);
String value = new String(col.getValue(),"utf-8") ;
assertTrue( value.equals("testInsertAndGetAndRemove_value_"+i) ) ;
}
//remove value
for(int i = 0 ; i < 100 ; i++){
ks.remove("testInsertAndGetAndRemove_"+i, cp);
}
try{
ks.remove("testInsertAndGetAndRemove_not_exist", cp);
}catch(Exception e){
fail("remove not exist row should not throw exceptions");
}
//get already removed value
for(int i = 0 ; i < 100 ; i++){
try{
Column col = ks.getColumn("testInsertAndGetAndRemove_"+i, cp);
fail("the value should already being deleted");
}catch(NotFoundException e){
}catch(Exception e){
fail("throw out other exception, should be NotFoundException." + e.toString() );
}
}
pool.releaseClient(cl) ;
pool.close() ;
KeySpace ks = cl.getKeySpace("Keyspace1") ;
// insert value
ColumnPath cp = new ColumnPath("Standard1" , null, "testInsertAndGetAndRemove".getBytes("utf-8"));
for(int i = 0 ; i < 100 ; i++){
ks.insert("testInsertAndGetAndRemove_"+i, cp , ("testInsertAndGetAndRemove_value_"+i).getBytes("utf-8"));
}
//get value
for(int i = 0 ; i < 100 ; i++){
Column col = ks.getColumn("testInsertAndGetAndRemove_"+i, cp);
String value = new String(col.getValue(),"utf-8") ;
assertTrue( value.equals("testInsertAndGetAndRemove_value_"+i) ) ;
}
//remove value
for(int i = 0 ; i < 100 ; i++){
ks.remove("testInsertAndGetAndRemove_"+i, cp);
}
try{
ks.remove("testInsertAndGetAndRemove_not_exist", cp);
}catch(Exception e){
fail("remove not exist row should not throw exceptions");
}
//get already removed value
for(int i = 0 ; i < 100 ; i++){
try{
Column col = ks.getColumn("testInsertAndGetAndRemove_"+i, cp);
fail("the value should already being deleted");
}catch(NotFoundException e){
}catch(Exception e){
fail("throw out other exception, should be NotFoundException." + e.toString() );
}
}
pool.releaseClient(cl) ;
pool.close() ;
Acredito que este documento permita alavancar o interesse para outros projetos com a tecnologia NoSQL. Como sempre menciono: Colaborar atrai amigos, competir atrai inimigos... Sobre o autor: http://www.netitec.com.br/alessandro