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.