NoSQL – Apache Cassandra e C#

Para uma demonstração simples de como desenvolver um EndPoint de get/set com o Cassandra em .NET, utilizei a biblioteca Aquiles v0.6.4.2 (http://aquiles.codeplex.com/), que mesmo com pouca documentação, permite uma implementação fácil e bem intuitiva.

Por que criarei um EndPoint/WebService? Pois WebServices permitem facil interação com qualquer aplicação independente de plataforma.

O primeiro passo foi adicionar e referenciar as DLLs da biblioteca em um projeto Web Service:

Configurei o web.config, de acordo com meu cenário (onde o Cassandra esta no ‘localhost’, porta 9160):

  <configSections>
    ...
    <section name="aquilesConfiguration" type="Aquiles.Configuration.AquilesConfigurationSection,Aquiles"/>
  </configSections>

  <aquilesConfiguration>
    <clusters>
      <add friendlyName="LocalCassandra">
        <connection poolType="SIZECONTROLLEDPOOL" factoryType="BUFFERED"/>
        <endpointManager type="ROUNDROBIN" defaultTimeout="6000">
          <cassandraEndpoints>
            <add address="localhost" port="9160"/>
          </cassandraEndpoints>
        </endpointManager>
      </add>
    </clusters>
  </aquilesConfiguration>

E criei um WebService bem simples utilizando o keyspace ToyStore do artigo anterior:

using System;
using System.Web.Services;

namespace CassandraEndPoint
{
    using Aquiles.Command;
    using Aquiles;
    using Aquiles.Helpers.Encoders;

    [WebService]
    public class wsToyStore : WebService
    {
        const string cassandraConn = "LocalCassandra";
        const string columnFamily = "Toys";
        const string keyspace = "ToyStore";

        [WebMethod]
        public string GetToyColumn(string key, string columnName)
        {
            AquilesHelper.Initialize();

            var cmd = new GetCommand
            {
                KeySpace = keyspace,
                ColumnFamily = columnFamily,
                Key = key
            };

            cmd.ColumnName = ByteEncoderHelper.UTF8Encoder.ToByteArray(columnName);

            using (var connection = AquilesHelper.RetrieveConnection(cassandraConn))
            {
                connection.Open();
                connection.Execute(cmd);
                connection.Close();
            }

            if (cmd.Output == null)
                return string.Empty;

            var bytes = cmd.Output.Column.Value;

            var value = ByteEncoderHelper.UTF8Encoder.FromByteArray(bytes);

            return value;
        }

        [WebMethod]
        public void SetToyColumn(string key, string columnName, string value)
        {
            AquilesHelper.Initialize();

            var cmd = new InsertCommand
            {
                KeySpace = keyspace,
                ColumnFamily = columnFamily,
                Key = key
            };

            cmd.Column =
                new Aquiles.Model.AquilesColumn()
                {
                    ColumnName = ByteEncoderHelper.UTF8Encoder.ToByteArray(columnName),
                    Value = ByteEncoderHelper.UTF8Encoder.ToByteArray(value),
                    Timestamp = DateTime.Now.Ticks
                };

            using (var connection = AquilesHelper.RetrieveConnection(cassandraConn))
            {
                connection.Open();
                connection.Execute(cmd);
                connection.Close();
            }
        }
    }
}

E como resultado, o método SetToyColumn para inserir ou alterar o valor de uma coluna.

E o método GetToyColumn, para recuperar estes valores:

A biblioteca mais low-level que pode ser encontrada para trabalhar com Apache Cassandra e C# é a Thrift, mas podem ser encontradas outras mais high-level que até têm suporte á LINQ, como a Cassandraemon.

Abaixo a relação de bibliotecas:

Thrift:
http://incubator.apache.org/thrift

Aquiles:
http://aquiles.codeplex.com

Hector Sharp:
http://www.hectorsharp.com

Fluent Cassandra:
http://github.com/managedfusion/fluentcassandra

Cassandraemon:
http://cassandraemon.codeplex.com

NoSQL – Operações básicas do Apache Cassandra

Caminhando mais um pouco com o Apache Cassandra após a instalação, vamos nos conectar ao servidor e realizar algumas operações, como criar uma “tabela”, inserir, alterar, consultar e remover registros.

Para isso, esteja com o “cassandra.bat” (servidor) rodando e utilize o arquivo “cassandra-cli.bat” (cliente) como prompt de comando para se conectar ao Cassandra, executando as seguintes linhas:

connect localhost/9160

Com o comando abaixo você irá listar as “tabelas” (keyspaces) que você tem em seu servidor:

show keyspaces

Para adicionar um novo keyspace, você terá que parar a aplicação fechando o prompt do “cassandra.bat”, em seguida, ir ao arquivo “conf\storage-conf.xml” e encontrar a tag “Keyspaces”:

Mesmo que poderíamos utilizar o Keyspace1 na demonstração, iremos adicionar uma segunda tag chamada Toys mais simples, que será nossa “tabela” de exemplo:

    <Keyspace Name="ToyStore">
      <ColumnFamily Name="Toys" CompareWith="UTF8Type" />
<ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
      <ReplicationFactor>1</ReplicationFactor>
      <EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
    </Keyspace>

Iniciando o “cassandra.bat”, conectando-se novamente com o prompt cliente teremos mais um keyspace:

Agora nosso primeiro “insert”, definimos que o registro com chave “Bola” terá “Azul” como valor para a coluna “Cor”:

set ToyStore.Toys['Bola']['Cor'] = 'Azul'

Agora atualizamos a “Cor” para “Vermelho” e adicionamos a coluna “Tamanho” com valor 3 (veja que teremos um erro com o valor 3, visto que definimos que trabalharíamos somente com UTF8Type (ou texto) na definição da ‘tabela’):

set ToyStore.Toys['Bola']['Cor'] = 'Vermelho'
set ToyStore.Toys['Bola']['Tamanho'] = 3

Para recuperar estes valores, utilizamos o comando get informando a chave do registro:

get ToyStore.Toys['Bola']

Ou também informando a coluna desejada:

get ToyStore.Toys['Bola']['Cor']

Por fim, um count:

count ToyStore.Toys['Bola']

E excluindo o registro:

del ToyStore.Toys['Bola']

Referência:
http://www.divconq.com/2010/how-to-add-and-retrieve-data-from-a-cassandra-database

NoSQL – Instalando o Apache Cassandra

Depois de uma breve explicação sobre o outro lado da moeda, vamos instalar e configurar o Apache Cassandra.

Primero passo, baixar uma versão binária estável:
http://cassandra.apache.org/download
(ex.: apache-cassandra-0.6.8-bin.tar.gz)

Descompactar:

Se você tentar executar o “cassandra.bat” na pasta bin:

Teremos o primeiro erro:

Então, antes verifique se você tem o Java 6 instalado em seu equipamento, se não tive instale:

Depois de instalar, verifique se dentre as variáveis de sistema existe JAVA_HOME definido.

1. Propriedades do computador:

2. Verifique se existe a variável JAVA_HOME configurada ou adicione uma nova:

3. Informe o nome da variável apontando para a pasta raiz do Java:

Com o Java instalado e configurado, vamos configurar os paths do Cassandra no arquivo storage-conf.xml da pasta conf:

Procure as seguintes linhas:

Onde estiver escrito “/var/lib/cassandra”, altere para o caminho da aplicação no Windows, exemplo “C:/Cassandra”:

Agora execute o cassandra.bat da pasta bin, e se tudo estiver ok, você terá a seguinte resposta:

INFO 22:42:28,061 Binding thrift service to localhost/127.0.0.1:9160
INFO 22:42:28,066 Cassandra starting up…

Pronto, servidor Apache Cassandra funcionando!

Referência:
http://support.qualityunit.com/knowledgebase/developers/cassandra/cassandra-installation-on-windows-7.html

Falando em NoSQL

Para que os leitores do blog também possam conhecer um pouco do outro lado da moeda, trabalharei alguns posts sobre o Apache Cassandra, que vende a ideia do NoSQL como uma tecnologia ótima para soluções de armazenamento de dados simples (key/value) e espalhados por vários servidores (cluster), com uma interação bem crua (get/set) simplesmente para manipular e consultar dados, lembrando também que um de seus principais clientes são o Facebook e o Twitter.

Mais informações:
http://cassandra.apache.org

Antes de utilizar o Apache Cassandra em produção, procure conhecer suas limitações (http://wiki.apache.org/cassandra/CassandraLimitations) e conversar bem com os profissionais de TI que têm familiaridade com esta tecnologia.