Troubleshooting pacemaker: La IP que configuro al pacemaker no apareix al ifconfig

Els que encara estem acostumats a fer servir ifconfig per administrar els nostres dispositius de xarxa ens trobem amb una dificultat quan posem una IP virtual al pacemaker, i és que no apareix. Si fem un “ip addr” si que la veiem entre totes les IP de la màquina. Perquè si que aparegui al ifconfig nomes hem de fer servir la opcio iflabel=”etiqueta”, i podrem veure la IP, i a més amb el “ip addr” sabrem a simple vista quina es la IP de la màquina i quina es la IP assignada a cadascun dels serveis de pacemaker:

#crm configure show
(...)
primitive IP_VIRTUAL ocf:heartbeat:IPaddr2
params ip="10.0.0.11" cidr_netmask="32" iflabel="IP_VIRTUAL"
op monitor interval="3s"
meta target-role="Started"
(...)

IMPORTANT: Les etiquetes dels dispositius nomes accepten 10 caràcters. Si en posem més, el pacemaker no podrà engegar la IP virtual i fallarà (això m’ha portat maldecaps :D). Assegureu-vos de posar 10 caràcters com a molt.

Sense iflabel no apareix al ifconfig ni està etiquetada al ip addr:

# ip addr
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:9e:3c:94 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.11/32 brd 10.0.0.11 scope global eth0
inet 10.0.0.12/32 brd 10.04.0.12 scope global eth0
inet 10.0.0.13/32 brd 10.0.0.13 scope global eth0
inet 10.0.0.14/32 brd 10.0.0.14 scope global eth0
inet6 fe80::250:56ff:fe9e:3c94/64 scope link
valid_lft forever preferred_lft forever
# ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:56:9E:3C:94
inet addr:10.0.0.1 Bcast:10.10.0.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:fe9e:3c94/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1825681745 errors:0 dropped:0 overruns:0 frame:0
TX packets:2044189443 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:576307237739 (536.7 GiB) TX bytes:605505888813 (563.9 GiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:924190306 errors:0 dropped:0 overruns:0 frame:0
TX packets:924190306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:415970933288 (387.4 GiB) TX bytes:415970933288 (387.4 GiB)


En canvi, amb el iflabel, si que apareixen:

[[email protected] ~]# ip addr
1: lo: mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:9e:3c:9c brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1./24 brd 10.254.1.255 scope global eth1
inet 10.0.0.11/32 brd 10.0.0.11 scope global eth1:nginx-ncnp
inet 10.0.0.12/32 brd 10.0.0.12 scope global eth1:nginx-clnp
inet 10.0.0.13/32 brd 10.0.0.13 scope global eth1:hap-ncnp
inet 10.0.0.14/32 brd 10.254.1.14 scope global eth1:hap-clnp
inet6 fe80::250:56ff:fe9e:3c9c/64 scope link
valid_lft forever preferred_lft forever
[[email protected] ~]# ifconfig
eth1 Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:fe9e:3c9c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:322545491 errors:0 dropped:0 overruns:0 frame:0
TX packets:333825895 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:92667389749 (86.3 GiB) TX bytes:93365772607 (86.9 GiB)

eth1:hap-clnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.12 Bcast:10.254.1.52 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth1:hap-ncnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.11 Bcast:10.254.1.51 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth1:nginx-clnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.13 Bcast:10.254.1.32 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth1:nginx-ncnp Link encap:Ethernet HWaddr 00:50:56:9E:3C:9C
inet addr:10.0.0.14 Bcast:10.254.1.30 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4073 errors:0 dropped:0 overruns:0 frame:0
TX packets:4073 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1136055 (1.0 MiB) TX bytes:1136055 (1.0 MiB)

Molt millor així :)

Més informacio aqui: http://linux.die.net/man/7/ocf_heartbeat_ipaddr2

Instal·lant graphite 0.9.10 a debian squeeze

El sistema de gràfiques que més m’agrada es el graphite. És molt útil per molts motius (és agil, es senzill, es escalable, consumeix molt pocs recursos, etc, etc). Avui parlaré de com s’instal·la el graphite 0.9.10 en Debian squeeze.

Primer de tot instal·lem els requisits:

apt-get install python apache2 python-twisted python-memcache libapache2-mod-python python-django libpixman-1-0 python-cairo python-django-tagging

I ens assegurem que no tenim instal·lat el whisper del repositori de debian, que és antic i pot tenir incompatibilitats amb la ultima versió de graphite:

apt-get remove python-whisper

Després instal·lem l’aplicació. Jo he fet uns .deb que poden fer-se servir directament:

wget http://www.tomas.cat/blog/sites/default/files/python-carbon_0.9.10_all.deb
wget http://www.tomas.cat/blog/sites/default/files/python-graphite-web_0.9.10_all.deb
wget http://www.tomas.cat/blog/sites/default/files/python-whisper_0.9.10_all.deb
dpkg -i python-carbon_0.9.10_all.deb python-graphite-web_0.9.10_all.deb python-whisper_0.9.10_all.deb

Però si no t’agrada fer servir els meus, es fàcil fer-los tu mateix amb el fpm (Effing package managers), una aplicació ruby que permet fer paquets per diferents gestors de paquets. Primer instal·lem ruby i fpm:

apt-get install ruby rubygems
gem install fpm

Després baixem el graphite i el descomprimim:

wget http://pypi.python.org/packages/source/c/carbon/carbon-0.9.10.tar.gz#md5=1d85d91fe220ec69c0db3037359b691a
wget http://pypi.python.org/packages/source/w/whisper/whisper-0.9.10.tar.gz#md5=218aadafcc0a606f269b1b91b42bde3f
wget http://pypi.python.org/packages/source/g/graphite-web/graphite-web-0.9.10.tar.gz#md5=b6d743a254d208874ceeff0a53e825c1
tar zxf graphite-web-0.9.10.tar.gz
tar zxf carbon-0.9.10.tar.gz
tar zxf whisper-0.9.10.tar.gz

I finalment creem els paquets i els instal·lem:

/var/lib/gems/1.8/gems/fpm-0.4.22/bin/fpm --python-install-bin /opt/graphite/bin -s python -t deb carbon-0.9.10/setup.py
/var/lib/gems/1.8/gems/fpm-0.4.22/bin/fpm --python-install-bin /opt/graphite/bin -s python -t deb whisper-0.9.10/setup.py
/var/lib/gems/1.8/gems/fpm-0.4.22/bin/fpm --python-install-lib /opt/graphite/webapp -s python -t deb graphite-web-0.9.10/setup.py
dpkg -i python-carbon_0.9.10_all.deb python-graphite-web_0.9.10_all.deb python-whisper_0.9.10_all.deb

Ja tenim l’aplicació instal·lada. El whisper no necessita cap configuració. El carbon si, però amb els fitxers que venen per defecte ja fem:

cp /opt/graphite/conf/carbon.conf.example /opt/graphite/conf/carbon.conf
cp /opt/graphite/conf/storage-schemas.conf.example /opt/graphite/conf/storage-schemas.conf

Aquest storache-schemas.conf fa que es guardin les dades cada minut només durant un dia. Com que segurament voldrem dades de mes temps (un mes, un any…), el que poso jo al storache-schemas.conf és el següent:

[default_1min_for_1month_15min_for_2years]
pattern = .*
retentions = 60s:30d,15m:2y

D’aquesta manera es guarden les dades cada minut durant 30 dies, i cada 15 minuts durant 2 anys. Això fa que les dades per cada gràfica ocupin en disc 1’4MB, un tamany raonable. Pots jugar amb aquests números si necessites més temps o vols ocupar menys espai en disc, és força intuitiu.

Despres s’ha d’inicialitzar la base de dades perquè es puguin començar a guardar les dades:

cd /opt/graphite/webapp/graphite
sudo python manage.py syncdb

I ara podriem engegar el carbon per començar a recollir dades executant el següent:

cd /opt/graphite/
./bin/carbon-cache.py start

Però també voldrem que s’engegi quan s’engega la màquina, per tant ho haurem d’afegir al init.d. Com que no ve cap script d’engegada amb l’aplicació, jo vaig baixar un init.d de graphite per RedHat i vaig fer quatre modificacions perque funcionés a debian:

#!/bin/bash
#
# Carbon (part of Graphite)
#
# chkconfig: 3 50 50
# description: Carbon init.d

. /lib/lsb/init-functions
prog=carbon
RETVAL=0

start() {
log_progress_msg "Starting $prog: "

PYTHONPATH=/usr/local/lib/python2.6/dist-packages/ /opt/graphite/bin/carbon-cache.py start
status=$?
log_end_msg $status
}

stop() {
log_progress_msg "Stopping $prog: "

PYTHONPATH=/usr/local/lib/python2.6/dist-packages/ /opt/graphite/bin/carbon-cache.py stop > /dev/null 2>&1
status=$?
log_end_msg $status
}

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
PYTHONPATH=/usr/local/lib/python2.6/dist-packages/ /opt/graphite/bin/carbon-cache.py status
RETVAL=$?
;;
restart)
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart|status}"
exit 1
esac

exit $RETVAL

Per instal·lar-ho només ho hem de baixar i posar-ho on toca:

wget http://www.tomas.cat/blog/sites/default/files/carbon.initd -O /etc/init.d/carbon
chmod 0755 /etc/init.d/carbon
chkconfig --add carbon

Ara ja podem engegar-ho des del initd (service carbon start o també /etc/init.d/carbon start). Finalment, configurem la webapp que permet accedir a les dades. Hem de crear un virtualhost al apache amb el següent contingut:


ServerName YOUR_SERVERNAME_HERE
DocumentRoot "/opt/graphite/webapp"
ErrorLog /opt/graphite/storage/log/webapp/error.log
CustomLog /opt/graphite/storage/log/webapp/access.log common


SetHandler python-program
PythonPath "['/opt/graphite/webapp'] + sys.path"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE graphite.settings
PythonDebug Off
PythonAutoReload Off

Alias /content/ /opt/graphite/webapp/content/

SetHandler None


Configurem el virtualhost i li donem accés a les dades del whisper:

wget http://www.tomas.cat/blog/sites/default/files/graphite-vhost.txt -O /etc/apache2/sites-available/graphite
a2ensite graphite
chown -R www-data:www-data /opt/graphite/storage/
/etc/init.d/apache reload

I ja ho tenim! Un últim detall… El graphite ve configurat amb el fus horari de Los Angeles. Per canviar-ho, s’ha d’assignar la variable “TIME_ZONE” al fitxer /opt/graphite/webapp/graphite/local_settings.py. Tens un fitxer amb un munt de variables que es poden tocar a /opt/graphite/webapp/graphite/local_settings.py.example, però com que l’únic que jo necessito canviar és el fus horari, executo la comanda:

echo "TIME_ZONE = 'Europe/Madrid'" > /opt/graphite/webapp/graphite/local_settings.py

I amb aixo ja ho tenim tot. Ara només ens caldrà enviar dades al carbon (port 2003) perquè s’emmagatzemin al whisper i la webapp del graphite les pugui mostrar. A gaudir!

Bibliografia: He seguit la documentació oficial http://graphite.wikidot.com/installation i http://graphite.wikidot.com/quickstart-guide, pero el mes específic relatiu a Debian ho he tret de http://slacklabs.be/2012/04/05/Installing-graphite-on-debian/

Troubleshooting pacemaker: Discarding cib_apply_diff message (xxx) from server2: not in our membership

Ahir, en reiniciar un dels nodes que tenim en alta disponibilitat (per actualitzar les maleïdes vmware-tools que es carreguen el meu preciós uptime) vam trobar-nos amb un problema greu, i és que el pacemaker no se sincronitzava, i per tant haviem perdut l’alta disponibilitat. El node actiu veia el cluster com si no hi hagués cap problema:

[[email protected]]# crm status
============
Last updated: Wed Nov 7 12:36:01 2012
Last change: Tue Nov 6 18:33:15 2012 via crmd on server2
Stack: openais
Current DC: server2 - partition with quorum
Version: 1.1.7-6.el6-148fccfd5985c5590cc601123c6c16e966b85d14
2 Nodes configured, 2 expected votes
6 Resources configured.
============

Online: [ server2 server1 ]
(...)

En canvi, el node passiu veia el cluster com si tots els nodes, inclòs ell mateix, estigues off-line:

[[email protected] ]# crm status
============
Last updated: Wed Nov 7 12:36:27 2012
Last change: Wed Nov 7 12:35:57 2012 via cibadmin on server1
Stack: openais
Current DC: NONE
2 Nodes configured, 2 expected votes
6 Resources configured.
============

OFFLINE: [ server2 server1 ]

Mirant els logs del node passiu vèiem que l’arrencada anava be, pero en cert moment començàven a sortir errors del tipus:

Nov 6 16:40:29 server1 cib [4607]: warning: cib_peer_callback: Discarding cib_replace message (776) from server2: not in our membership
Nov 6 16:40:29 server1 cib[4607]: warning: cib_peer_callback: Discarding cib_apply_diff message (777) from server2: not in our membership

En el node actiu no sortia cap missatge que ens semblés estrany. Mirant el corosync, vam comprobar que els nodes es podien veure entre ells sense problema. Els dos nodes tornàven el mateix:

[[email protected] ]# corosync-objctl | grep member
runtime.totem.pg.mrp.srp.members.200.ip=r(0) ip(10.10.10.10)
runtime.totem.pg.mrp.srp.members.200.join_count=1
runtime.totem.pg.mrp.srp.members.200.status=joined
untime.totem.pg.mrp.srp.members.201.ip=r(0) ip(10.10.10.11)
runtime.totem.pg.mrp.srp.members.201.join_count=1
runtime.totem.pg.mrp.srp.members.201.status=joined

Amb un tcpdump escoltant el port del corosync vam comprobar que hi havia trànsit (cosa evident, pero en aquests casos ho proves tot), amb la qual cosa semblava clar que el problema era de pacemaker i també molt clar que no teniem ni idea del què era. Investigant vam trobar uns quants enllaços (per exemple aquest: http://comments.gmane.org/gmane.linux.highavailability.pacemaker/13185) on deien que es un bug, que se soluciona amb aquest commit https://github.com/ClusterLabs/pacemaker/commit/03f6105592281901cc10550b8ad19af4beb5f72f que entrava a la versio 1.1.8 de pacemaker. I nosaltres tenim la 1.1.7. Glups.

Per assegurar, en comptes d’actualitzar la màquina existent, vam crear una nova i vam instal·lar pacemaker de zero, seguint les instruccions de http://www.clusterlabs.org/rpm-next/ i de http://www.clusterlabs.org/wiki/Install. Bàsicament vam fer:

wget -O /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm-next/rhel-6/clusterlabs.repo
yum install -y corosync corosynclib corosynclib-devel pacemaker cman

Vam copiar el corosync.conf adaptant-lo (bàsicament, canviant-li el nodeid) i el vam engegar, i va integrar-se al cluster sense cap problema:

[[email protected]]# crm status

Last updated: Wed Nov 7 18:14:08 2012
Last change: Wed Nov 7 18:07:01 2012 via cibadmin on balance03
Stack: openais
Current DC: balance03 - partition with quorum
Version: 1.1.8-1.el6-394e906
3 Nodes configured, 3 expected votes
6 Resources configured.

Online: [ server3 server2 ]
OFFLINE: [ server1 ]
(...)

Vam poder fer un migrate al nou node i tot va funcionar perfectament. Vam actualitzar els altres i vam recuperar la nostra alta disponibilitat de nou.

Però la nova versió ve amb inconvenients, i és que crm, l’eina que feiem servir per configurar pacemaker, ara es distribueix per separat, a petició del mantenidor. S’ha convertit en un projecte per si mateix amb el nom crmsh, i té la seva propia web: http://savannah.nongnu.org/projects/crmsh/. El paquet compilat es pot descarregar d’aquí http://download.opensuse.org/repositories/network:/ha-clustering/ pero té dependència del paquet pssh, que al seu torn té algunes altres dependències. En resum, vam haver de fer el següent:


wget http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/pssh-2.0-1.el6.rf.noarch.rpm
rpm -Uvh pssh-2.0-1.el6.rf.noarch.rpm
yum -y install python-dateutil.noarch
yum -y install redhat-rpm-config
wget http://download.opensuse.org/repositories/network:/ha-clustering/CentOS_CentOS-6/x86_64/crmsh-1.2.5-55.3.x86_64.rpm
rpm -Uvh crmsh-1.2.5-55.3.x86_64.rpm

I amb això ja ho teniem tot en marxa de nou

Troubleshooting cassandra: Saved cluster name XXXX != configured name YYYY

Si alguna vegada ens trobem que el cassandra no engega, i el log ens apareix el següent error:

INFO [SSTableBatchOpen:3] 2012-10-31 16:51:35,669 SSTableReader.java (line 153) Opening /cassandra/data/system/LocationInfo-hd-56 (696 bytes)
ERROR [main] 2012-10-31 16:51:35,717 AbstractCassandraDaemon.java (line 173) Fatal exception during initialization
org.apache.cassandra.config.ConfigurationException: Saved cluster name XXXX != configured name YYYY
at org.apache.cassandra.db.SystemTable.checkHealth(SystemTable.java:299)
at org.apache.cassandra.service.AbstractCassandraDaemon.setup(AbstractCassandraDaemon.java:169)
at org.apache.cassandra.service.AbstractCassandraDaemon.activate(AbstractCassandraDaemon.java:356)
at org.apache.cassandra.thrift.CassandraDaemon.main(CassandraDaemon.java:107)

El problema es que el nom de cluster que apareix al fitxer de configuracio ($CASSANDRA_HOME/conf/cassandra.yaml) es diferent al que hi ha configurat al valor LocationInfo[utf8(‘L’)][utf8(‘ClusterName’)] dintre de la base de dades. Per arreglar-ho, o bé hem de canviar un o bé hem de canviar l’altre.

Canviar el fitxer de configuració es obvi, però si volem canviar l’altre haurem de fer servir el cassandra-cli:

$CASSANDRA_HOME/bin/cassandra-cli -h localhost
use system;
set LocationInfo[utf8('L')][utf8('ClusterName')]=utf8('');
exit;

Això ens pot passar quan volem portar les dades de cassandra d’un cluster a un altre (per exemple, d’un entorn productiu a un entorn que no ho és), o simplement si volvem canviar el nom del cluster de cassandra per qualsevol motiu.

Instal·lació bàsica de apache cassandra (i algunes millores de fine tuning)

Darrerament he treballat molt amb clusters de apache Cassandra, així que aprofitaré per escriure uns quants articles al respecte. Començaré amb el més obvi: la instal·lació de Cassandra. Es un procès molt senzill que encara es pot fer mes fàcil amb els .rpm o .deb que ja existeixen. Però jo ho faré independent de la distro perquè pugui ser útil per tothom, sense importar la distro que faci servir.

1- Prerrequisit: Instal·lar Java Virtual Machine

Per començar, apache cassandra és una aplicació Java, per tant necessitarem la màquina virtual de java (jvm) per poder-la fer servir. Sabem que hi ha vàries versions (openjdk, per exemple), però és molt recomanable fer servir la versió oficial de Sun / Oracle, que podem trobar en el seguent enllaç: http://www.java.com/en/download/linux_manual.jsp?locale=en, o podem instal·lar-la fent servir els gestor de paquets de cada distro (acostuma a estar empaquetada, com a mínim per les principals: redhat, debian, centos, etc).

2- Descàrrega de Cassandra

Després baixem la versió que volguem de Cassandra. Si es la nostra primera instal·lació, voldrem la darrera versió, i la trobarem a la pàgina principal del seu lloc web (ara mateix es la 1.1.6). Després la descomprimim a on volguem (normalment seria /opt però aquí cadascú té les seves preferències) i fem un enllaç simbòlic d’aquest directori a “/opt/cassandra“, per facilitar futures actualitzacions.

cd /opt
wget http://apache.rediris.es/cassandra/1.1.6/apache-cassandra-1.1.6-bin.tar.gz
tar zxvf apache-cassandra-1.1.6-bin.tar.gz
ln -s apache-cassandra-1.1.6 cassandra

3- Gestionant els permisos de l’usuari cassandra

Un bon costum es no donar més privilegis a un servei dels que li fan falta. Per tant, crearem un usari “cassandra” que serà l’usuari amb el que correrà el nostre procés. I ja de pas crearem els directoris que necessitarà l’aplicació per funcionar (logs, pids, etc)

adduser cassandra
mkdir /var/log/cassandra
chown -R cassandra /var/log/cassandra/
mkdir /var/run/cassandra
chown -R cassandra /var/run/cassandra/
mkdir /var/lib/cassandra
chown -R cassandra /var/lib/cassandra/
chown -R cassandra /opt/cassandra/

4- Cassandra com a servei del sistema

Ara voldrem engegar-ho com un servei del sistema. Amb la distribució oficial no ve cap script d’arrencada, però aquí tenim un de stàndard:

wget http://www.tomas.cat/blog/sites/default/files/cassandra.initd -O /etc/init.d/cassandra
chmod a+x /etc/init.d/cassandra
chkconfig --add cassandra
chkconfig cassandra on

Això farà que poguem engengar i aturar cassandra com un servei més del sistema, i que s’engegi quan es reinicia el servidor.

5- Canvis en la configuració de cassandra

Amb això ja tenim un cassandra funcionant amb un sol node. Potser voldrem fer alguns canvis bàsics a la configuració, per exemple la RAM destinada a Cassandra. Per defecte es destina la meitat de la RAM disponible a la HEAP de java, i 100MB per cada CPU de la màquina, pero això es pot modificar al fitxer /opt/cassandra/conf/cassandra-env.sh. També en aquest fitxer es poden modificar les opcions de la cmdline de java, el port de JMX i més coses. Es força auto-explicatiu.

Un altre fitxer que potser ens interessa es /opt/cassandra/conf/cassandra.yaml, on podrem configurar moltes coses, per exemple on es guarden les dades, o l’adreça IP i port pels que volem que el nostre cassandra escolti. Exemples:

  • rpc_address: adreça per on volem que escolti per thrift. Hem de posar una adreça IP de la màquina (pot ser localhost si volem) o 0.0.0.0 si volem que escolti per totes
  • data_file_directories: directori on volem que guardi les dades
  • commitlog_directory: directori on volem que guardi el commit_log
  • saved_caches_directory: directori on volem que guardi les caches

En cas que volguem fer un cluster, també ens interessaran els següents paràmetres:

  • cluster_name: quin nom li volem posar al cluster (ha de ser el mateix per tots els nodes, i MOLT IMPORTANT, diferent entre diferents clusters perque no es trepitgin entre ells)
  • initial_token: el token que li toca a aquest node
  • listen_address: adreça per on volem que es comuniqui per gossip. No pot ser localhost ni 0.0.0.0, perquè la resta de nodes intentaran connectar a l’adreça que digui aquí.
  • seeds: a quin servidor ha de demanar la llista de nodes que formen part del cluster

6 – Fine tune

Hi ha una sèrie de coses que no estan activades per defecte, però que milloren substancialment l’estabilitat i eficiència de cassandra. Jo els posso sempre! Son els següents:

6.1- Fine tune 1 – Script d’arrencada apte per processos d’automatització o batch

El script d’arrencada (init.d) que hem configurat abans té una limitació pel meu parer, i és que, en ser java, el script d’engegada i d’aturada només envia el senyal adient al proces (ja sigui “engega” o “atura’t”) i surt. Per tant, no podem tenir confirmació REAL de que el servei ha engegat correctament, i si un dels nostres processos batch depén d’això, doncs estem fotuts. Per això he afegit unes línies que comproven amb un netcat si el port de thrift està escoltant i, per tant, si el cassandra està actiu i en marxa, abans de retornar a la shell. Les línies en qüestió són les següents:

Primer extreiem dels fitxer de configuracio l’adreça i el port:

CASS_CLI_ADDRESS=cat $CASS_HOME/conf/cassandra.yaml|grep rpc_address|cut -d":" -f2
CASS_CLI_PORT=cat $CASS_HOME/conf/cassandra.yaml|grep rpc_port|cut -d":" -f2

I després en la funció “start” afegim aquesta comprovació:

nc -z -w 1 $CASS_CLI_ADDRESS $CASS_CLI_PORT
while [ $? -ne 0 ]; do
[ date -r $CASS_LOG +%s -lt date -d "$TIMEOUT_LOG minutes ago" +%s ] && echo "Too much time of inactivity in the log file. Aborting..." && exit 1 ;
[ $start_date -lt date -d "$TIMEOUT_STARTUP minutes ago" +%s ] && echo "It's taking too long to start. Aborting..." && exit 1;
sleep 10;nc -z -w 1 $CASS_CLI_ADDRESS $CASS_CLI_PORT; done

Es una mica cutre, però funcional. Quan retornem a la shell tindrem la garantia que el cassandra està en marxa. . Si vols la versió “tunejada”, pots seguir aquest altre procés:

wget http://www.tomas.cat/blog/sites/default/files/cassandra_tuned.initd -O /etc/init.d/cassandra
chmod a+x /etc/init.d/cassandra
chkconfig --add cassandra
chkconfig cassandra on

Recordeu que aquest script necessita del netcat, per tant haureu d’instal·lar-lo per tal que funcioni (“yum install nc“, “apt-get install netcat“, o el que correspongui).

6.2- Fine tune 2 – Habilitar Java Native Access (JNA) a cassandra

L’acces a disc, entre d’altres coses, millora considerablement si es fan servir les llibreries natives del SO en comptes de les de java, que son lentes i consumeixen molts recursos. Aixè ho aconseguim instal·lant JNA, que fa de pont entre el Java i les llibreries natives. Instal·lar-ho es tan fàcil com posar els .jar al directori /opt/cassandra/lib, i cassandra els reconeixerà automàticament

wget https://github.com/twall/jna/blob/3.5.1/dist/jna.jar?raw=true -O /opt/cassandra/lib/jna.jar
wget https://github.com/twall/jna/blob/3.5.1/dist/platform.jar?raw=true -O /opt/cassandra/lib/platform.jar

Podem assegurar-nos que l’està fent servir si mirem el log de cassandra (/var/log/cassandra/system.log). Si no està, apareix aquest missatge:

INFO [main] 2012-09-26 16:52:40,051 CLibrary.java (line 62) JNA not found. Native methods will be disabled.

Si el cassandra l’ha reconegut correctament, apareix aquest altre:

INFO [main] 2012-10-30 16:41:00,970 CLibrary.java (line 109) JNA mlockall successful

6.3- Fine tune 3 – Apujar el limit de Open Files per cassandra

Si li donem una mica de canya, es freqüent que el cassandra necessiti mes de 1024 fitxers oberts (el màxim per defecte). Per evitar que això ens porti problemes, haurem d’editar el fitxer /etc/security/limits.conf i pujar el límit. Un valor prudent es 65536:

root soft nofile 65536
root hard nofile 65536
cassandra soft nofile 65536
cassandra hard nofile 65536

6.4- Fine tune 4 – Limitar la memòria destinada a Cassandra

Finalment, tots coneixem Java i sabem que pots dir-li que faci servir com a màxim certa quantitat de memòria, pero és molt probable que faci servir més memòria. Entre la memòria de la aplicació, més el heap, més el overhead, etc, podem trobar-nos un procés java, configurat per fer servir 8GB de memoria, fent servir 16GB o més. Per assegurar que això no ens passarà, i garantir que la màquina no es quedarà sense memòria, es recomanable posar-hi un límit. En el nostre cas hem considerat oportú posar la meitat de la memòria de la màquina, al fitxer /etc/security/limits.conf :

root soft memlock 8388608
root hard memlock 8388608
cassandra soft memlock 8388608
cassandra hard memlock 8388608

7 – Comprovació de que Cassandra està en marxa

I amb això ja ho tenim tot llest, només hem d’engegar el daemon (“/etc/init.d/cassandra start” o “service cassandra start” o el que correspongui). I podem comprobar el funcionament tant amb el nodetool (es connecta a cassandra via JMX) o amb el cassandra-cli (es connecta a cassandra via thrift). La sortida serà una semblant a aquesta:

[[email protected] ~]# /opt/cassandra/bin/nodetool -h localhost ring
Note: Ownership information does not include topology, please specify a keyspace.
Address DC Rack Status State Load Owns Token
127.0.0.1 datacenter1 rack1 Up Normal 11,21 KB 100,00% 66508542233540571552076363838168202092
[[email protected] ~]# /opt/cassandra/bin/cassandra-cli -h localhost
Connected to: "Test Cluster" on localhost/9160
Welcome to Cassandra CLI version 1.1.6

Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.

[[email protected]] describe cluster;
Cluster Information:
Snitch: org.apache.cassandra.locator.SimpleSnitch
Partitioner: org.apache.cassandra.dht.RandomPartitioner
Schema versions:
59adb24e-f3cd-3e02-97f0-5b395827453f: [127.0.0.1]

[[email protected]] quit;
[[email protected] ~]#

I final!! ja tenim una instal·lació bàsica de cassandra mínimament tunejada.