Testeando Apache Cassandra

12-08-2014
 
Cassandra Logo

Cassandra Logo

Estos días he estado jugando con Cassandra, la que parece la reina de las bases de datos NoSql. También he querido comprobar su rendimiento con respecto a MySql, lo cual me ha sorprendido bastante.

La primera conclusión a la que he llegado es que la guerra de las bases de datos, no es una guerra por el rendimiento, sino por la especialización. Las redes sociales y el Big Data obligan a guardar grandes cantidades de datos distribuidos y requieren de una velocidad de respuesta en las lecturas muy grandes(Si tu web no carga en menos de 0.5 segundos estas fuera). Cassandra entiende esto, aportando una velocidad de respuesta y elasticidad(Capacidad para crecer en numero de nodos sin problemas) muy grande.

Instalación de Cassandra

La instalación de Cassandra es muy sencilla, solamente hay que descargar de su web(http://cassandra.apache.org/download/) y descomprimir en la carpeta ‘/opt'(Los de Linux).

Una vez hemos descomprimido solo hay que ejecutar ‘/bin/cassandra.sh’ como administrador, podéis añadir el parámetro -f si no queréis que se os abra como servicio.

Test de rendimiento

Para el test de rendimiento he desarrollado este pequeño programa en Java que lee las palabras de un fichero de texto ‘pg2701.txt'(Yo me descargué “Moby dick” del proyecto Gutenberg http://www.gutenberg.org/ ). El driver de DataStax para Java(http://www.datastax.com/download#dl-datastax-drivers).

Cree dos bases de datos, una en Cassandra y otra en MySql con una sola tabla llamada ‘palabras’ y dos campos: ‘id INT PRIMARY KEY’ y ‘palabra TEXT’.

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.BoundStatement;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.DriverManager;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Vector;
import java.util.Date;

public class Test {

	static public void main(String[] params) {
		try {
			System.out.println( "Leyendo registros a procesar..." );

			Vector<String> words=new Vector<String>();

			BufferedReader br = new BufferedReader(new FileReader("pg2701.txt"));
			String line = br.readLine();

        		while (line != null) {
				String[] w=line.split(" ");
				for ( int i=0; i<w.length; i++ ) words.add( w[i] );

            			line = br.readLine();
        			}

			br.close();

			System.out.println( "Total a processar: "+words.size() );

			System.out.println( "\nTest Mysql:\n=============================== " );
			testMysql( words );

			System.out.println( "\nTest Cassandra:\n=============================== " );
			testCassandra( words );
		} catch (Exception ex) { ex.printStackTrace(); }
		}

	static public void testMysql(Vector<String> words) throws Exception {
		long time=0;
	    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=root&password=");
		Statement st = conn.createStatement();

		time=new Date().getTime();
		st.execute("truncate palabras");
		System.out.println("TRUNCATE "+(new Date().getTime()-time)+"ms");
		
		time=new Date().getTime();
		int i=1;
		PreparedStatement pstm=conn.prepareStatement("insert into palabras(id,palabra) values(?,?)"); 
		for ( String w:words ) {
			pstm.setInt(1,i); 
			pstm.setString(2,w); 

			pstm.executeUpdate(); 

			i++;
			}
		System.out.println("INSERT "+(new Date().getTime()-time)+"ms");

		time=new Date().getTime();
		st.execute("select * from palabras");
		System.out.println("SELECT "+(new Date().getTime()-time)+"ms");

		conn.close();
		}

	static public void testCassandra(Vector<String> words) throws Exception {
		long time=0;
	    	Cluster cluster = Cluster.builder().addContactPoint("127.0.0.1").build();
		Session session = cluster.connect("test1");

		time=new Date().getTime();
		session.execute("truncate palabras");
		System.out.println("TRUNCATE "+(new Date().getTime()-time)+"ms");
		
		time=new Date().getTime();
		int i=1;
		com.datastax.driver.core.PreparedStatement statement = session.prepare( "insert into palabras(id,palabra) values (?,?)" );

		for ( String w:words ) {
			session.execute( statement.bind( i,w ) );

			i++;
			}
		System.out.println("INSERT "+(new Date().getTime()-time)+"ms");

		time=new Date().getTime();
		ResultSet results = session.execute("select * from palabras");
		System.out.println("SELECT "+(new Date().getTime()-time)+"ms");

		cluster.close();
		}
	}

He ejecutado el script varias veces con diferentes cantidades de datos y la respuesta siempre a sido parecida a esta:

Cassandra Test 1

Cassandra Test 1

Análisis de los datos

La verdad es que los datos se tienen que coger un poco con pinzas, porque, aunque todo se ha probado en la misma máquina no todos los parámetros han sido iguales. Además hay parámetros que no se han probado, como por ejemplo, tener montado un cluster.

Cassandra parece ser mas lenta con las operaciones de escritura, en cambio, es muchísimo mas rápida en las operaciones de lectura, y parece que a mas operaciones de lectura, mas se incrementa esta diferencia.

En conclusión, Cassandra parece ser ideal para los grandes proyectos Web y de Big Data. No en vano, la están usando Facebook(Quién la creó), Twitter o Digg entre muchos otros actores de la web 2.0

Comments

One Response to “Testeando Apache Cassandra”
  1. […] de datos es mejor que sea una base de datos especializada, por ejemplo, bases de datos NoSQL como Cassandra mucho mas rápidas para este tipo de […]

Leave a Reply

© Albert Coronado Calzada