Mostrando postagens com marcador framework. Mostrar todas as postagens
Mostrando postagens com marcador framework. Mostrar todas as postagens

quinta-feira, 13 de fevereiro de 2014

Easy-Cassandra, a versão 2.0.1

Lançada a nova versão do Easy-Cassandra, a versão 2.0.1, dentre as novidades podemos citar;
  • Refatoração nos contrutores das fábricas de sessão
  • QueryBuilder (InsertBuilder, UpdateBuilder, DeleteBuilder, SelectBuilder e BatchBuilder)
  • Maior velocidade na leitura e escrita
  • Suporte nos processos assíncronos
  • Maior suporte ao Cassandra com Spring-Data
Um ponto importante é que para facilitar a configuração foi criada uma classe que é passada no parâmetro, a classe ClusterInformation, dessa maneira fica mais simples (além do código mais limpo, afinal sobrecarga de construtores não é uma boa prática) de se criar simples configurações para a fábrica. Como, por exemplo:

ClusterInformation clusterInformation = ClusterInformation.create()
                .addHost(HOST)
                .withDefaultKeySpace(KEY_SPACE).withUser(USER).withPassword(PASS);
        easyCassandraManager = new EasyCassandraManager(clusterInformation);

Criando configuração para a fábrica de conexão
Dessa forma a configuração para usar o Spring no Cassandra também mudou para:





 
 
  
   localhost
  
 



 
 
  
   org.easycassandra.persistence.cassandra.spring.entity.Contact
            org.easycassandra.bean.model.Step
            org.easycassandra.bean.model.Weight
  
 



 



Nova configuração do Spring no Easy-Cassandra
Talvez a melhoria mais marcante nessa versão são os recursos dos QueryBuilders, os queryBuilders são maneiras muito mais fácil de fazer interações com o Cassandra com configurações adversas de uma maneira mais simples, com ele é possível definir o nível de consistência, definir o timeStamp, quais campos serão manipulados.

 SimpleID id = new SimpleID();
    id.setIndex(ONE_HUNDRED_THIRTY);
    id.setKey(ONE_HUNDRED_THIRTY);
    UpdateBuilder update = template.updateBuilder(SimpleQueryBuilder.class, key);
    update.put("map", "name", "otavioMap").value("value", TEN_DOUBLE).execute();

Simples exemplo inserindo valores a partir da chave
UpdateBuilder update = persistence.updateBuilder(SimpleQueryBuilder.class);
 update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).addList("list", "otavioList").execute();

criando toda a query de atualização
 UpdateBuilder update = persistence.updateBuilder(SimpleQueryBuilder.class);
 update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).value("value", 12D).executeAsync(new ResultAsyncCallBack() {
    @Override
    public void result(Boolean bean) {
        // do some action
    }
});
executando uma atualização assincronamente
InsertBuilder insert= persistence.updateBuilder(SimpleQueryBuilder.class);
Set set = new HashSet<>();
set.add("Linda");
Map map = new HashMap<>();
map.put("love", "Otavio and Poliana");
insert.value(Constant.KEY, Constant.ONE_HUNDRED).value(Constant.INDEX,
            Constant.ONE_HUNDRED).value(Constant.LIST_COLUMN, Arrays.asList("Poliana", "Otavio", "Love")).value(Constant.SET_COLUMN, set).value("map", map).execute();

Realizando inserção
  SimpleID id = new SimpleID();
    id.setIndex(ONE_HUNDRED_TWO);
    id.setKey(ONE_HUNDRED_TWO);
    SimpleBean simpleBean = new SimpleBean();
    simpleBean.setId(id);
    simpleBean.setValue(VALUE);
    InsertBuilder insert2 = persistence.updateBuilder(simpleBean);
    insert2.executeAsync((new ResultAsyncCallBack() {
    @Override
    public void result(Boolean bean) {
        // do some action
    }
    });
realizando inserção de modo assíncrono
  DeleteBuilder delete = persistence.deleteBuilder(SimpleQueryBuilder.class); 
    delete.whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute();

    DeleteBuilder delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class,"map", "list", "set"); //Delete specific columns
    delete2 .whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute();

primeira query remove todas as colunas a partir da chave, na segunda query remove apenas os campos map, list e set.
 SimpleID id = new SimpleID();
    id.setIndex(ONE_HUNDRED_TWO);
    id.setKey(ONE_HUNDRED_TWO);

    DeleteBuilder delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class, id);
    delete2.executeAsync((new ResultAsyncCallBack() {
    @Override
    public void result(Boolean bean) {
        // do some action
    }
    });
remoção assíncrona
  SelectBuilder select = persistence.selectBuilder(SimpleQueryBuilder.class);
  select.eq("name", "name");
  select.in("index", ONE, TWO, THREE);
  List result = select.execute();

Realizando o select em que o campo nome é igual a nome e o indice está em um, dois e três.
SelectBuilder select = persistence.selectBuilder(SimpleQueryBuilder.class);
select.eq(NAME, NAME).gt("index", THREE).asc(INDEX).executeAsync(new ResultAsyncCallBack>() {

        @Override
        public void result(List beans) {
          // do some thing
        }
    });
Executando query assincronamente em que o indece seja mais que três e seja ordenado de forma descendente no índice.
O Batch é um recurso no cassandra que permite que se execute alterações no banco (inserção, atualização e remoção) de forma atômica, desse forma se pode enviar insert, updates e deletes como se fosse apenas uma requisição.

DeleteBuilder delete = dao.deleteBuilder();
    delete.whereEq(Constant.INDEX, Constant.ONE_HUNDRED_TWO)
            .whereEq(Constant.KEY, Constant.ONE_HUNDRED_TWO);

    InsertBuilder insert = dao.insertBuilder();
    insert.value(Constant.KEY, Constant.ONE_HUNDRED).value(Constant.INDEX,
            Constant.ONE_HUNDRED);
    insert.value(Constant.LIST_COLUMN,
            Arrays.asList("Poliana", "Otavio", "Love"));

    UpdateBuilder update = dao.update();
    update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE);
    update.addList("list", "otavioList");

    BatchBuilder batchBuilder = dao.batchBuilder();

    batchBuilder.addOperations(delete, insert, update);
    batchBuilder.executeAsync(new ResultAsyncCallBack() {
        @Override
        public void result(Boolean bean) {
            // do some action
        }
    });
Executando processo de inserção, remoção e atualização de forma atômica com o BatchBuilder.
Vale lembrar que recurso do Batch deve ser usados em casos específicos, já que distribuir as requisições entre os nós, no cassandra, sempre será sua melhor amiga.
Esse artigo tem como objetivo ilustrar as mudanças dentro do Easy-Cassandra, se demonstrou dos recursos e da sua melhoria na velocidade a expectativa é que muitos mais recursos estejam por vir.
  1. https://github.com/otaviojava/Easy-Cassandra/wiki/Builders
  2. https://github.com/otaviojava/Easy-Cassandra/wiki
  3. https://github.com/otaviojava/Easy-Cassandra/
  4. https://github.com/otaviojava/Easy-Cassandra-samples

sexta-feira, 2 de março de 2012

Usando Easy-Cassandra 1.0.8 com maven



       Lançada a mais nova versão do framework Easy-Cassandra seu objetivo é estar facilitando a comunicação entre Apache Cassandra e sua aplicação em java. Com ele é possível esta criando, atualizando, recuperando ou deletando os seus objetos java de uma maneira bastante simples, para isso basta apenas realizar anotações na classe e nos campos.

CARACTERÍSTICAS



  • Uma espécie de ORM para o Cassandra
  • Precisa apenas de anotações na classe para persistir informações
  • Persiste muito objetos java de uma maneira bastante fácil
  • Escreve e ler no Cassandra com Level Consistency.
  • O primeiro compatível com versões acima do Cassandra 0.8
  • Compatível com CQL 2.0
  • O primeiro a usar invokedynamic ao invés de Reflection
  • Sob a licença Apache versão 2.0
  • Suporte aos seguintes objetos


As novidades nessa versão:


  • Criação de Famílias de colunas e índices secundários em tempo de execução
  • Suporte ao CQL 2.0
  • suporte a chamada de chaves com 'in'




    Para demonstrar essa nova versão será apresentado um exemplo prático com uma aplicação simples. Essa aplicação terá o objetivo de armazenar informações da média de renda dos brasileiros agrupados por CEP, a ideia seria saber quanto é gerado em reais e o número de entidades comerciais ( padarias, mercados, mercadinhos, açougues etc.) que geram esse valor em um determinado local, CEP. Assim será armazenado aproximadamente 640 mil informações a cada levantamento de estudo.
Cada requisição para o estudo terá as seguintes informações:


  • Código do Lote
  • Quantidade de pessoas calculadas no setor CEP
  • Valor computado
  • Cidade
  • Logradouro
  • Bairro
  • Cep
  • Tipo do logradouro
  • Estado
  • Sigla


    Para armazenar essas informações será utilizado o banco nosql Cassandra que é:


  1. Altamente confiável:
    Utilizado por diversas empresas entre elas Cisco, Reddit, Twitter. O maior cluster conhecido do Cassandra possui mais de 300 tb em 400 máquinas .
  2. Tolerante a falhas :
    Os dados são replicados automaticamente para múltiplos nós para a tolerância a falhas.
  3. Descentralizado :
    Já que não existe ponto de falha nem gargalhos de rede. Já que cad nós é idêntico .
  4. Configurável:
    Se pode escolher de uma maneira bastante simples se será uma atualização síncrona ou assíncrona além de possuir Hinted Handoff e Read Repair .
  5. Escalável :
    Com ele tanto a escalabilidade horizontal e vertical poderão ser feitas de uma maneira bastante simples. Além de adicionar novas máquinas podem ser adicionadas sem tempo de interrupção .
  6. Durável :
    Foi projeto para não perder informações mesmo quando vários nós falham.


    Para facilitar o desenvolvimento será utilizado o Easy-Cassandra que funcionará como uma camada de acima do Thrift facilitando as chamadas para o Cassandra, aumentando a produtividade além de deixar o código mais limpo. Para seu funcionamento é necessário baixar a lib do framework além de suas dependências (mais informações no final do artigo). Para facilitar o gerenciamento dessas lib nesse exemplo será utilizado o maven, para ter acesso o projeto é necessário adicionar o repositório além da tag da lib conforme mostra a tabela 1.



Tabela1: chamada do repositório e chamada da lib do Easy-Cassandra

Cada requisição representará uma linha no Cassandra que pode varia o seu tamanho de linha por linha. Assim mapeando as requisições com as anotações ficará de acordo com a tabela 2.


@ColumnFamilyValue(name = "controle")
public class ControleRenda implements Serializable {

@KeyValue(auto = true)
private Long id;
@EmbeddedValue
private Endereco endereco;
@ColumnValue(name = "valor")
private Double valor;
@ColumnValue(name = "quantidade")
private Long quantidade;
//getter and setter
}

public class Endereco implements Serializable {

@ColumnValue(name="cidade")
private String cidade;
@ColumnValue(name="logradouro")
private String logradouro;
@ColumnValue(name="bairro")
private String bairro;
@IndexValue
@ColumnValue(name="cep")
private String cep;
@ColumnValue(name="tp_logradouro")
private String tp_logradouro;
@ColumnValue(name="estado")
private String estado;
@ColumnValue(name="sigla")
private String sigla;
// getter and setter
}

Tabela 2: Mapeamento das classes para o controle de renda por cep


    Ao ver a tabela 2 na classe Endereço existe a anotação @IndexValue no campo cep, essa anotação faz com que esse campo seja um índice secundário, um campo que além da chave pode recuperar informações dentro da linha. Com isso nessa linha além do código de controle ( coluna chave) a linha pode ser recuperada pelo cep ( campo chave secundária).
Para simular essas requisições foi utilizado um arquivo texto com aproximadamente 640 mil linhas. Cada linha possui as informações separado por pipe '|'.
Para rodar o nosso exemplo é necessário que o Cassandra esteja rodando já que tanto a família de colunas tanto a chave secundária serão criados em tempo de execução graças ao um recurso da nova versão.


create keyspace renda;



    Assim basta executar a aplicação e todas as informações estarão persistiradas no cassandra. De fato existe inúmeras maneiras de aumentar a performance do cassandra (configurando o GC, configurando o heap, aumentando o número de nós e clusters, etc.), mas nesse exemplo foi mostrado usando os recursos padrões.
Nesse artigo foi demonstrado um exemplo prático utilizando o Easy-Cassandra 1.0.8 junto com o maven, realizando um programa simples com 640 requisições. Foi demonstrado alguns novos recursos como a criação da família de coluna e a chave secundária em tempo de execução.


Referências:




Documentação, lib e código exemplo (Maven_Example.rar): https://github.com/otaviojava/Easy-Cassandra/downloads