RSS

NoSQL (III): Java + Cassandra DB

06 Sep

La segunda de las demos que vamos a realizar en esta serie de artículos es la de Cassandra DB. Podéis encontrar la página del proyecto en este enlace. Cassandra DB es una base de datos hibrida entre una de “clave-valor” y una “orientada a fila”, ya veremos que es esto más adelante. De momento, no nos preocupemos. Como dato curioso comentar simplemente que, aunque ahora es un proyecto de Apache, el inicio de este desarrollo lo realizo Facebook, si los mismos de la red social.

Instalando Cassandra DB

Lo primero que tenemos que hacer es ir a la página del proyecto y descargarnos la última versión que en el momento de escribir este artículo es la 1.1.4. El fichero comprimido que nos descargamos contiene todo lo necesario para trabajar con Cassandra, en este caso no hace falta descargarse ningún Driver aparte. De nuevo, decir que estoy haciendo esto sobre Windows 7 y no sobre Linux, aunque espero que al igual que en la demo anterior, los procesos no sean muy diferentes y no tengáis problemas para seguir la demo. He mirado el directorio de ejecutables de Cassandra y los ficheros de configuración vienen preparados para Linux también.

En este caso, como ya he comentado no hay Driver de conexión propiamente dicho en la página web para descargar, o al menos yo no lo he visto. La ventaja de estar haciendo esto en Java es que Cassandra está desarrollado sobre Java, con lo cual solo vamos a necesitar las librerías que vienen en el fichero que hemos descargado. Para el resto de lenguajes, ahora mismo no tengo ni idea, de nuevo si alguien lo esta haciendo en un lenguaje distinto a Java y se anima a mandar la contribución, esta será publicada tras una breve revisión. Como único dato importante que puedo aportar sobre esto, os dejo el enlace a una de las páginas del Wiki oficial del proyecto con ejemplo de diferentes lenguajes.

Una vez descargado el fichero con la base de datos, solo tendréis que descomprimirlo donde deseéis y ya tendréis instalada la bases de datos Cassandra. En este caso, al igual que en el anterior, el directorio que había dentro del zip, lleva todos los ejecutables necesarios para poder trabajar con Cassandra. Además, tiene un directorio con ficheros de configuración y uno con las librerías.

Así que, lo primero de todo como siempre, vamos a probar la base de datos a ver si conseguimos arrancarla y verla funcionando. Lo primero que tendremos que hacer es definir dos variables globales en nuestro sistema.

  • JAVA_HOME: Ruta donde se aloja nuestra instalación de Java.
  • CASSANDRA_HOME: Ruta donde tendremos alojada la instalación de Cassandra.

Al contrario que con MongoDB que solo era una sugerencia aquí es obligatorio definirlas ya que los scripts de arranque chequean si están definidas o no. En el caso de JAVA_HOME, si no está definida nos mostrará un error, pero en el caso de CASSANDRA_HOME, tiene una definida por defecto.

Tras esto simplemente nos dirigimos a la ruta donde hayamos puesto nuestro directorio Cassandra y entramos en el directorio bin para ejecutar la base de datos.

promt> cd %CASSANDRA_HOME%\bin

promt> cassandra.bat

Con esto obtendremos un mensaje similar a este, lo que nos confirmará que el arranque ha ido bien:

Listening for thrift clients…

Ahora vamos a tratar de conectar a la base de datos con el cliente que está en la misma ruta

promt> cassandra-cli.bat

Esto ejecutará un cliente de conexión para acceder a Cassandra, en el promt que nos aparece tenemos a nuestra disposición la instrucción help que nos mostrará diferentes opciones, en nuestro caso vamos a utilizar la de connect. Remarcar que las instrucciones se ejecutan con un punto y coma al final (ej. help;) si no el promt no reaccionará al texto que hayamos introducido. Para conectar a nuestro servidor Cassandra, vamos a ejecutar la siguiente instrucción:

promt> connect localhost/9160;

Que nos mostrará algo similar a:

Connected to: “Test Cluster” on localhost/9160

En este punto os animo a que juguéis un poco con los comandos disponibles, al menos echadle un ojo a los show y daros cuenta de los create existentes.

No he encontrado, quizás la haya pero lo desconozco, que Cassandra venga con una consola de administración web como lo hacía, por ejemplo, MongoDB. Lo que si sé que hay es un proyecto alojado en Google Code con un proyecto de interfaz web. Os dejo aquí el enlace por si queréis probarlo: CassUI.

Previamente a empezar a escribir el código Java, vamos a crear nuestro esquema (keyspace) en la base de datos y nuestra tabla (column family). Para ello en el promt escribiremos lo siguiente:

promt> create keyspace helloks;

promt> use helloks;

promt> create column family hcolumn;

Conectando desde Java

Para empezar, de nuevo, lo primero que tendremos que hacer es crear un proyecto Java básico, también podéis utilizar el mismo proyecto que creamos para la demo de MongoDB, simplemente cread una clase nueva y ya está.

Del mismo modo que lo hicimos para añadir el Driver en MondoDB, aquí tendremos que añadir las librerías de Cassandra a nuestro proyecto. Dichas librerías están en el directorio de Cassandra en lib (%CASSANDRA_HOME%\lib). Las librarías a añadir serán:

  • apache-cassandra-thrift-x.x.x.jar
  • libthrift-x.x.x.jar
  • sl4j-api-x.x.x.jar

Tras esto escribiremos el código de nuestro primer ejemplo. En este caso el código lo vamos a coger del wiki mencionado anteriormente ya que está bastante bien, y solo tendremos que hacerle unos pequeños cambios para adaptarlos a nuestra bases de datos:


public static void main(String[] args) throws TException,
InvalidRequestException, UnavailableException,
UnsupportedEncodingException, NotFoundException, TimedOutException {
TTransport tr = new TFramedTransport(new TSocket("localhost", 9160));
TProtocol proto = new TBinaryProtocol(tr);
Cassandra.Client client = new Cassandra.Client(proto);
tr.open();

String key_user_id = "1";

// insert data
long timestamp = System.currentTimeMillis();
client.set_keyspace("helloks");
ColumnParent parent = new ColumnParent("hcolumn");

Column nameColumn = new Column(toByteBuffer("name"));
nameColumn.setValue(toByteBuffer("svoboda"));
nameColumn.setTimestamp(timestamp);
client.insert(toByteBuffer(key_user_id), parent, nameColumn,
ConsistencyLevel.ONE);

Column ageColumn = new Column(toByteBuffer("age"));
ageColumn.setValue(toByteBuffer("99"));
ageColumn.setTimestamp(timestamp);
client.insert(toByteBuffer(key_user_id), parent, ageColumn,
ConsistencyLevel.ONE);

ColumnPath path = new ColumnPath("hcolumn");

// read single column
path.setColumn(toByteBuffer("name"));
System.out.println(client.get(toByteBuffer(key_user_id), path,
ConsistencyLevel.ONE));

// read entire row
SlicePredicate predicate = new SlicePredicate();
SliceRange sliceRange = new SliceRange(toByteBuffer(""),
toByteBuffer(""), false, 10);
predicate.setSlice_range(sliceRange);

List<ColumnOrSuperColumn> results = client.get_slice(
toByteBuffer(key_user_id), parent, predicate,
ConsistencyLevel.ONE);
for (ColumnOrSuperColumn result : results) {
Column column = result.column;
System.out.println(toString(column.name) + " -> "
+ toString(column.value));
}

tr.close();
}

public static ByteBuffer toByteBuffer(String value)
throws UnsupportedEncodingException {
return ByteBuffer.wrap(value.getBytes("UTF-8"));
}

public static String toString(ByteBuffer buffer)
throws UnsupportedEncodingException {
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
return new String(bytes, "UTF-8");
}

Tras ejecutar este pequeño programita, veremos el siguiente resultado:


ColumnOrSuperColumn(column:Column(name:80 01 00 02 00 00 00 03 67 65 74 00 00 00 04 0C 00 00 0C 00 01 0B 00 01 00 00 00 04 6E 61 6D 65, value:80 01 00 02 00 00 00 03 67 65 74 00 00 00 04 0C 00 00 0C 00 01 0B 00 01 00 00 00 04 6E 61 6D 65 0B 00 02 00 00 00 07 73 76 6F 62 6F 64 61, timestamp:1346925753115))
age -> 99
name -> svoboda

Como podéis ver, aunque quizás el resultado obtenido tras la ejecución al leer la columna completa y mostrarla no es muy intuitivo, el manejo de la base de datos y el acceso de almacenamiento y lectura de los datos concretos si lo es, y además, muy fácil. Espero que hayáis conseguido llegar hasta aquí con éxito y que os haya servido para familiarizaros con Cassandra. Nos vemos.

Anuncios
 
13 comentarios

Publicado por en 6 septiembre, 2012 en NoSQL

 

13 Respuestas a “NoSQL (III): Java + Cassandra DB

  1. silver account

    11 septiembre, 2012 at 6:13 am

    Thrift es tan solo el protocolo de conexión para poder utilizar Cassandra. Aunque en la extensión para PHP existen métodos para poder trabajar con cassandra, requieren bastante código por eso utilizaremos PHPCassa como abstracción de la base de datos.

     
    • svoboda

      12 septiembre, 2012 at 2:42 pm

      Gracias por la información. La verdad es que como he dicho a lo largo de los diferentes posts, no he trabajado con NoSQL con otros lenguajes que no sean Java, así que cualquier información sobre esto es bien recibida. Un saludo.

       
  2. alfonso

    26 marzo, 2013 at 7:32 am

    como emigro una base de datos relacional a cassandra clic alguien me puede dar un ejemplo

     
  3. pabloE

    23 mayo, 2013 at 10:28 pm

    Como conecto cassandra-cli con jsp en netbeans. Si me podrías ayudar te lo agradezco.

     
    • svoboda

      23 mayo, 2013 at 10:48 pm

      Pues básicamente puedes hacer un bean al que acceder desde el jsp, y que rellenes desde una clase que tenga las consultas que desees sobre cassandra. No es diferente a como harías con cualquier otra BBDD en cualquier otro tipo de proyecto.

       
  4. pabloE

    25 mayo, 2013 at 6:12 pm

    Tengo este codigo para conectar a postgres desde jsp

    public class conexion {
    Connection conexion;
    Statement sentencia;
    PreparedStatement ps;
    String usuario, password, ip, puerto, bdatos;

    public conexion()throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException{
    this.usuario = “postgres”;
    this.password = “postgres”;
    this.ip = “127.0.0.1”;
    this.puerto = “5432”;
    this.bdatos = “hoja”;
    this.conexionPostgres();
    }

    private void conexionPostgres()throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException{
    Class.forName(“org.postgresql.Driver”).newInstance();
    this.conexion = DriverManager.getConnection (“jdbc:postgresql://”+ip+”:”+puerto+”/”+bdatos,usuario,password);
    this.sentencia = (Statement) this.conexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
    }

    public Connection getConexion() throws SQLException{
    return this.conexion;
    }

    public void close() throws SQLException{
    this.conexion.close();
    this.sentencia.close();
    }
    }

    Para cassandra-cli que tocaria modificar?

     
    • svoboda

      26 mayo, 2013 at 8:03 am

      Más o menos sería así ya que no tengo lugar ahora mismo donde probarlo. Te he dejado algunas cosas comentadas (los throws):

      public class Conexion {
      TTransport tr;
      TProtocol proto;
      Cassandra.Client client;
      String usuario, password, ip, puerto, keyspace;
      Map credenciales;

      public conexion()throws … /* Añadir excepciones que correspondan */ {
      this.usuario = “cassandra”;
      this.password = “cassandra”;
      this.ip = “127.0.0.1″;
      this.puerto = “9160″;
      this.keyspace = “yourkeyspace”;
      this.conexionCassandra();
      }

      private void conexionCassandra()throws … /* Añadir excepciones que correspondan */ {
      tr = new TFramedTransport(new TSocket(ip, puerto));
      proto = new TBinaryProtocol(tr);
      client = new Cassandra.Client(proto);
      credenciales = new HashMap();
      credenciales.put(SimpleAuthenticator.USERNAME_KEY, usuario);
      credenciales.put(SimpleAuthenticator.PASSWORD_KEY, password);
      tr.open();
      client.set_keyspace(this.keyspace);
      client.login(this.keyspace, new AuthenticationRequest(credenciales));
      }

      public Cassandra.Client getClient() throws … /* Añadir excepciones que correspondan */ {
      return this.client;
      }

      public void close() throws … /* Añadir excepciones que correspondan */ {
      this.tr.close();
      }
      }

      Espero que te sirva. Un saludo.

       
  5. Anónimo

    13 junio, 2013 at 3:39 am

    sl4j-api-x.x.x.jar hay problemas no crea un conexion

     
    • svoboda

      13 junio, 2013 at 6:38 pm

      Si no eres más concreto con el error que tienes, me temo que no te puedo ayudar. Yo no tuve ningún problema al implementar esta pequeña demo.
      ¿Has revisado tu configuración de red? Cortafuegos y esas cosas…

       
  6. pabloE

    13 junio, 2013 at 11:11 pm

    Gracias por el aporte..

     
    • svoboda

      18 junio, 2013 at 9:02 pm

      ¡Gracias! Me alegro que te sea útil.

       

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: