domingo, 25 de marzo de 2012

Cassandra cluster, facil facil!!

La verdad que como con todas las cosas, eres libres de complicarlas tanto como quieras, pero en este caso complicar la instalación y configuración de un cluster en cassandra es dificil ;).

Para este escenario vamos a suponer que tenemos tres nodos de cassandra:

test01 (192.168.30.21)
test02 (192.168.30.22)
test03 (192.168.30.23)

Es una buena idea que metas estas lineas en el /etc/hosts con todos tus nodos de cassandra ya que a cassandra no le termina de gustar los nombres FQDN:

192.168.30.21    test01
192.168.30.25    test02
192.168.30.26   test03

El siguente paso, como no instalar cassandra, para ello vamos a instalarlo de paqueteria de debian, pero instalar de fuentes es igualmente facil, como requisito necesitas tener instalado java.
Metemos la siguiente linea en el fichero /etc/apt/sources.list:

deb http://www.apache.org/dist/cassandra/debian 10x main
deb-src http://www.apache.org/dist/cassandra/debian 10x main 

Ahora al hacer un apt-get update te saltara un error de este tipo:

GPG error: http://www.apache.org unstable Release: The following signatures couldn't 
be verified because the public key is not available: NO_PUBKEY F758CE318D77295D
 
Pues bien, apunta la clave publica y lanzas:
 
gpg --keyserver pgp.mit.edu --recv-keys F758CE318D77295D
gpg --export --armor F758CE318D77295D | apt-key add - 

Y:

gpg --keyserver pgp.mit.edu --recv-keys 2B5C1B00
gpg --export --armor 2B5C1B00 | apt-key add -
 
Esta segunda es tal cual te la pego aqui.
 
Ahora si, hacemos un apt-get update y luego el apt-get install cassandra y ya lo tienes instalado.
 
 
Pues bien, ahora para poner en marcha el cluster tenemos que asignar un token a cada uno de los nodos, yo que usado un script en python que te lo calcula en funcion del numero de nodos que le pases, el script son apenas 10  lineas:

  1 #! /usr/bin/python
  2 import sys
  3 if (len(sys.argv) > 1):
  4     num=int(sys.argv[1])
  5 else:
  6     num=int(raw_input("How many nodes are in your cluster? "))
  7 for i in range(0, num):
  8     print 'token %d: %d' % (i, (i*(2**127)/num))

En definitiva en el fichero principal de configuracion /etc/cassandra/cassandra.yaml hay que cambiar la configuracion de las siguientes entradas:

test01:
  cluster_name: 'MyDemoCluster'
  initial_token: 0
  seed_provider:
      - class_name: org.apache.cassandra.locator.SimpleSeedProvider
        parameters:
            - seeds: test01
  listen_address: test01
  rpc_address: 0.0.0.0
  endpoint_snitch: org.apache.cassandra.locator.RackInferringSnitch

test02:
  cluster_name: 'MyDemoCluster'
  initial_token: 56713727820156410577229101238628035242
  seed_provider:
      - class_name: org.apache.cassandra.locator.SimpleSeedProvider
        parameters:
            - seeds: test01
  listen_address: test02
  rpc_address: 0.0.0.0
  endpoint_snitch: org.apache.cassandra.locator.RackInferringSnitch


test03:
  cluster_name: 'MyDemoCluster'
  initial_token: 113427455640312821154458202477256070485
  seed_provider:
      - class_name: org.apache.cassandra.locator.SimpleSeedProvider
        parameters:
            - seeds: test01
  listen_address: test03
  rpc_address: 0.0.0.0
  endpoint_snitch: org.apache.cassandra.locator.RackInferringSnitch
 
Como nota decir que la directiva endpoint_snitch se usa para que cassandra conozca 
como está la topologia de red y puede ser SimpleSnitch, RackInferringSnitch o 
PropertyFileSnitch.
Apuntar tambien que el seed server es en este caso test01, esto no es ni mas ni menos
 el servidor al cual se conectaran los nuevos nodos que añadamos al cluster para actualizar 
sus datos en primera instancia, el seed server no es un punto de fallo para el funcionamiento 
cotidiano del cluster.
 

Ahora solo queda jugar!!!


viernes, 16 de marzo de 2012

Problemas de acceso a disco con vmware y debian 6

Hola a todos, despues de casi 11 meses sin escribir ninguna entrada, hoy me he levantado con ganas ... ;)

Ultimamente me ha tocado pelearme mucho (bueno y a mis compañeros también) con herramientas de stress para optimizar el rendimiento del sistema operativo, en nuestro caso el pauperrimo acceso a disco que da la debian 6 cuando está montada sobre un ESX (4.1 o 5).

En nuestro caso en particular hemos usado sysbench. Hay muchas herramientas de este tipo, pero más allá de entrar en debate de cual es mejor o peor, lo importante es realizar los test con de manera homogenea para que los resultados sean lo más reveladores posible.

Bueno, poniendo un poco al personal en antecedentes, nuestra problematica como he dicho anteriormente viene tras detectar el pobre acceso a disco  (a los discos locales) que estabamos teniendo en nuestra plataforma, todo en debian 6 sobre ESX 4.1 de VMWARE.

Para realizar el test de disco hemos hecho un script que al final llama al sysbech y nos saca la tasa de transferencia de las operaciones a disco realizadas:

#!/bin/sh
for i in 1 2 8 16 32
do
echo "hilos $i"
for j in 1
do
echo "  intento $j"
sysbench --num-threads=$i --test=fileio --file-test-mode=rndrd --file-extra-flags=direct --max-requests=10000 prepare > /dev/null
sysbench --num-threads=$i --test=fileio --file-test-mode=rndrd --file-extra-flags=direct --max-requests=10000 run | grep transferred
sysbench --num-threads=$i --test=fileio --file-test-mode=rndrd --file-extra-flags=direct --max-requests=10000 cleanup > /dev/null
done
echo "___________________"
done

El script como vereis hace 5 veces con 1, 2, 8, 16 y 32 thread simultaneos. Lo normal cuando lanzas el test sobre un disco es que te de menos tasa de transferecia con 1 hilo y que la cosa vaya subiendo a medida que le metes hilos hasta que se estabiliza.

Pues bien la primera cosa que vimos fue que la tasa de transferecia era lineal, es decir, daba aproximadamente la misma tasa de transfercia con 1 hilo que con 32, raro, raro, raro....

La segunda cosa que vimos fue como podeis ver mas abajo que la tasa de transferecia era bajisima, apenas 9MB/s para estar montadas las imagenes de vmware montadas sobre una bandeja de discos en fiber channel de un almacenamiento EMC.

Si quereis saber las IOPS que son 9MBps la formula es facil:
  IOPS = (MBps Throughput / KB per IO) * 1024
Aqui KB por IO es 16K que es tamaño de bloque que sysbench usa por defecto en una operacion de entrada/salida

En nuestro caso y siguiendo esa formula son 575 IOPS.

 Aqui os pego el test con los resultados:

root@pre1 ~/kk $ /root/bin/benchmark_disk.sh
hilos 1
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (8.9316Mb/sec)
___________________
hilos 2
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (9.2897Mb/sec)
___________________
hilos 8
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (8.8921Mb/sec)
___________________
hilos 16
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (9.4219Mb/sec)
___________________
hilos 32
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (9.2804Mb/sec)


Como podeis apreciar, bastante bajo y lineal.


Pues bien, despues de estar persiguiendo este problema con el fabricante, leer mucho al respecto y hacer 1001 pruebas, a uno de nuestros compis se le encendio la bombilla y como por arte de magia cambiando un parametro todo empezo a funcionar a toda velocidad.

Que? Ya os creiais que os iba a dejar asi, sin contaros la solución verdad? ;)

La clave del asunto esta en el scheduler de las colas de acceso al disco. Y os preguntareis que es esto del scheduler, bueno, pues para los que no lo sepais, sin exterme mucho y entrar en demasiados detalles es la forma que tiene el sistema operativo de gestionar de una manera optima las operaciones enviadas al disco.

Esto se hace através de una cola, en debian 6 hay cuatro diferentes (noop, cfq, anticipatory y deadline) , cada una gestiona los accesos al disco de una manera distinta pero como dato deciros que por defecto se suele usar la cfg.

Esta cola lo que hace a groso modo es reorganizar las operaciones de IO en le van llegando de una manera optima para que los movimientos mecanicos del disco sean los menos posibles.

Algunos (los que no se hayan dormido ya) habrán llegado a la conclusión por si solos de que hay determinadas ocasiones en las que no tiene mucho sentido este tipo de comportamiento, como podria ser con discos SSD que no tienen parte mecanica o cuando el acceso al disco se esta gestionando desde otra capa como es en nuestro caso VMWARE.

Pues bien para esto esta la cola de tipo noop, que es la cola más sencilla de las cuatro, es de tipo FIFO y todo lo que entra sale al disco sin ningun tipo de orden que no sea el de prioridad de entrada.

Este parametro lo encontrais aqui:

root@pre1 ~/kk $ cat /sys/block/sdb/queue/scheduler
noop anticipatory deadline [cfq]

Para cambiarlo basta con ejecutar este comando y vereis que el scheduler cambia a noop:
root@pre1 ~/kk $ echo noop > /sys/block/sda/queue/scheduler
root@pre1 ~/kk $ cat /sys/block/sdb/queue/scheduler
[noop] anticipatory deadline cfq

Una vez echo esto repetimos las pruebas con asombrosos resultados:

root@pre1 ~/kk $ /root/bin/benchmark_disk.sh
hilos 1
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (8.5274Mb/sec)
___________________
hilos 2
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (17.948Mb/sec)
___________________
hilos 8
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (36.151Mb/sec)
___________________
hilos 16
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (39.358Mb/sec)
___________________
hilos 32
  intento 1
Read 156.25Mb  Written 0b  Total transferred 156.25Mb  (64.089Mb/sec)


Ahora si que si, la curva crece a medida que le metes hilos y la tasa de transferecia es mucho mayor, llegando a 64MBps (aunque el sysbench ponga Mb en realidad son MB) con unas IOPS de 4096.

Bueno espero con esto arrojar luz sobre este tema que tanto tiempo nos ha hecho perder, mejor dicho invertir, ya que ahora sabemos un poquito más que ayer...

Ciao!!

P.D. Gracias a todo mi equipo que son unos fieras, Oscar, Dani, Rober y Fermin.