martes, 22 de julio de 2008

Vacaciones, Campus y "demases"

Bueno pues lo dicho, que con el calorcito, además de los agobios llegan las vacaciones, para casi todos que los hay que están peor..... ;)

Este año el tema se plantea..... de novedades y es que vere por 1ª vez la "campus" desde dentro

Las espectativas son bastante altas la verdad, por lo que me da un poco de miedo que el evento me defraude...... Ya veremos.

Bueno sin más....... me voy de vacaciones¡¡¡¡ ;)

martes, 8 de julio de 2008

Rendimiento en Mysql - Query Cache

Bueno, pues a base de "palos" y gracias a un proyecto del trabajo.... descubrí a ese gran amigo que es el "query-cache" de MySql...

Tras la implementación, he obtenido, mas menos... una ganancia de 3seg. por consulta, lo que en un sitio de mucha carga es una pasada. Además de esto estoy ahora mismo en un ratio "Hits/Inserts" de 2.7 lo cual me parece mas que aceptable de momento. Y lo mejor .... todo esto a costa de 16Mb de Ram, barato no ;)

Pequeño resumen de Query-Cache:
El Query-Cache, como su nombre indica es una cache para consultas de Mysql, no nos olvidemos que cualquier web almacenada en BD, sus paginas son consultas también.
Cuando se realiza una consulta en MySql, si no esta "cacheada", esta se inserta en la cache y se sirve el resultado. La siguiente vez que se realiza esta consulta, se sirve el resultado directamente de la cache. Coste teórico = 0.
Cuando una tabla o registro (segun si tenemos mysam, innodb....) se modifica en disco, los resultados referentes a esta en la cache son descartados.

*Sist. con muchas escrituras, inutilizará las entradas de cache demasiadas veces.

Bueno basta de royo.... la configuración, pruebas y resultados son los siguientes.

/etc/my.conf

.......
######################################
## CONFIGURACION CONEXIONES MAX ##
######################################
table_cache=1000
max_connections=500
######################################
## CONFIGURACION QUERY CACHE ##
######################################
query_cache_type = 1
query_cache_size = 16M
query_cache_limit = 2M
......

Cada parametro es para......
max_connections (Número máximo de conexiones de MySql)
table_cache (Número máximo de descriptores que abrira mysql a la vez. Segun el sistema de BD necesita, un numero de descriptores por conexion. En mi caso Myysam necesita 3, por lo que lo ideal seria 1500, pero ya que uno de ellos se cierra despues de abrirse, considere que 1000 estaba bien.) Si este valor es demasiado bajo on respecto a max_connection, el rendimiento cae en picado, y si es demasiado alto, podemos sobrepasar el limite del SO.o de MySql.

Limite de Mysql:
su -m mysql

ulimit -a
Limite de SO:
[root@nodo]# sysctl -a|grep file
fs.file-max=206210


query_cache_type (Cache ON)
query_cache_size (Tamaño de memoria para la cache, por defecto en RH es 0, por lo que aun estando a 1 el cahe_type, es como si estuviera parada ;)
query_cache_limit (Las consultas cuyos resultados sean mayores a este valor no seran cacheadas)
Ir probando los valores segun las necesidades y las posibilidades..

Una vez configurado esto... rebotamos el servicio y .... woalaaa¡¡

Verificando aciertos:

Desde Mysql..

mysql> show status like '%Qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1125 |
| Qcache_free_memory | 3122472 |
| Qcache_hits | 32118388 |
| Qcache_inserts | 11866396 |
| Qcache_lowmem_prunes | 11001043 |
| Qcache_not_cached | 542 |
| Qcache_queries_in_cache | 2949 |
| Qcache_total_blocks | 8342 |
+-------------------------+----------+
8 rows in set (0.00 sec)

Ratio Qcache_hits/Qcache_inserts=2.706

Verificando ganancias de tiempos de respuesta:

Antes de configurar nada... Se tomaron las siguientes medidas:

ab -n 30 -c 1 http://sitio_a_probar
"ab-Apache BenchMark"

Con esto se solicita el index.html 30 veces con una concurrencia(peticiones simultaneas) de 1, y se obtienen los tiempos de respuesta.
Tras la configuracion de la cache, se repite la medición y es aquí donde vemos realmente las ganacias obtenidas a costa de 16Mb

Conclusion:
Si la base de datos es principalmente de lectura... "sitio web", la ganancia es muy buena y la configuracion de la cache mas que recomendable.
Si la BD es principalmente de escritura, la ganancia se nota mucho menos, por lo que habría que estudiar el caso concreto.



Crontab no me ejecuta los scripts....

Hola, pues lo dicho, que el título le viene como anillo al dedo....

Hace ya algún tiempo ando con el problemita de marras...

Y es que mis scripts que se ejecutan perfectamente, si los lanzo a "mano", no se ejecutan si están programados en el cron.

Tras mirar y mirar encontré la solución en otro blog ;)

Solución:

Resulta que el problema reside en el "run-parts" que usa el cron para ejecutar los scripts....

Según el man:

“run-parts run all the executables files named within constraints described bellow, found in directory directory. Other files and directories are silently ignored.

If the –lsbsysinit option is not given the names must consist entirely of upper and lower case letters, digits, underscore, and hypens.

Pues va ha ser eso ;) (Nada como leer), no están soportados mas que los caracteres (letras, dígito, guiones y subrayados) así que mi script XXXX.sh, con ese precioso "punto", no cumple las restricciones.

Quitamos el punto y a correr.

Blog que me ayudó



viernes, 4 de julio de 2008

Recargando modulos Kernel - Mala instalación

mmmmm bueno... este "post" va en relación al anterior, aunque trata un tema que se puede extrapolar perfectamente, por eso he decidido no incluirlo, en el mismo "post".

Bueno.. a lo que estamos ;)

Descripción del problema

Durante la instalación del software de cluster en una de mis nodos, hubo varios problemas derivado de las versiones de software y kernel... con lo que al final e la instalación, no se habian generado los modulos del kernel necesarios, así que hubo que "reconstruirlos".


Solución Aplicada

Por suerte... como he dicho antes, esto ocurrió e uno de los nodos, por lo que los modulos de la discordia, existian en el otro nodo ;)

1.- Copiamos los modulos de uno de los nodos a el otro, por supuesto en la misma ubicación.

2.- Verificamos que los modulos no están siendo cargados en el kernel.

[root@nodo1 ~]# lsmod grep cman
[root@nodo1 ~]# lsmodgrep dlm

3.- Insertamos los módulos en el kernel

[root@nodo1 ~]# cd /lib/modules/2.6.9-55.EL/kernel/
[root@nodo1 kernel]# insmod cluster/cman.ko
[root@nodo1 kernel]# insmod cluster/dlm.ko

4.- Primer instentode arrancar... Fallido ;( aunque los modulos ya están insertados... ¿Faltará cargarlos? ;)

[root@nodo1 kernel]# service cman startStarting cman: [FALLÃ][root@nodo1 kernel]# lsmodgrep cman
cman 128448 1 dlm
[root@nodo1 kernel]# lsmodgrep dlm
dlm 128692 0
cman 128448 1 dlm

5.- Verificar y cargar módulos..

[root@nodo1 kernel]# modprobe cman
FATAL: Module cman not found.
[root@nodo1 kernel]# modprobe dlm
FATAL: Module dlm not found.

Efectivamente... no están cargados :)
Vamos a decirle al kernel que están ahi ;)

[root@nodo1 kernel]# depmod -a
[root@nodo1 kernel]# modprobe cman
[root@nodo1 kernel]# modprobe dlm

Ummmm esto ya tiene otra pinta ;), problema solucionado

[root@nodo1 kernel]# reboot

martes, 1 de julio de 2008

Cluster Red Hat 4 ES

Hace ya algún tiempo tuve que poner en funcionamiento un cluster de RH en un entorno de desarrollo formado por dos pc's normalitos con dos tarjetas de red cada uno (Requisito mínimo ;))
Este artículo viene a ser un "mini"resumen de los problemas y soluciones adoptadas para el montaje.

Descripción del problema

Montaje de un cluster RH activo/pasivo, para alta disponibilidad de diferentes servicios.
El HW con el que se cuenta, son dos pc's PIV con SO. RH4ES, con dos tarjetas ethernet cada uno.

Interfaces Nodo1:
eth0 - 192.168.56.15 (Conexión a la LAN)
eth1 - 10.0.0.2 (Cable cruzado, conexión test de servicio entre nodos)

Interfaces Nodo2:
eth0 - 192.168.56.33 (Conexión a la LAN)
eth1 - 10.0.0.1 (Cable cruzado, conexión test de servicio entre nodos)

En cada nodo, se crea una Interfaz virtual (Misma IP en ambos nodos, y deshabilitada en el arranque de las máquinas), la cual suministrara el servicio, para que de este modo, los clientes se conecten a la misma IP siempre, independientemente de que nodo tenga el servicio levantado. (eth0:1)

Instalación de Paquetes
Para la instalación de Cluster Suite, se obtiene la ISO desde la web de RH, y desde el entorno grafico, se instala automáticamente.

Configuración Previa

Antes de poder configurar los servicios del clúster, es necesario garantizar, que los nodos están configurados adecuadamente.

1.- Verificar el estado de las interfaces de Red. Podemos hacerlo de dos maneras distintas:

1.1.- En /etc/sysconfig/network-scripts/ deben existir entre otros, los ficheros “ifcfg-eth0”, “ifcfg-eth0:1”, “ifcfg-eth1”, en cada uno de estos ficheros esta la información referente a la configuración de esa interfaz .

1.2.- También se puede configurar en modo gráfico desde “AplicacionesConfiguración del sistemaRed”.
Una vez aquí, nos situamos en la pestaña de “Dispositivos” y seleccionamos “Nuevo”, tras esto seleccionamos el tipo de dispositivo, en nuestro caso “Conexión Ethernet”, luego nos pide seleccionar entre las tarjetas físicas que hay, seleccionamos la “eth0”, le damos una ip y nos creará la “eth0:1”


/etc/hosts

El clúster necesita que los equipos puedan, resolver las direcciones de todos los nodos, y a todas las interfaces, por lo que en cada nodo, se edita su fichero /etc/hosts, de la siguiente manera.


[root@nodo1 ~]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
192.168.56.15 nodo1.dominio nodo1
10.0.0.2 nodo1-hb.dominio nodo1-hb
192.168.56.33 nodo2.dominio nodo2
10.0.0.1 nodo2-hb.dominio nodo2-hb



uname –a

El clúster, dentro de su fichero de configuración “/etc/cluster/cluster.conf”, especifica el nombre de los nodos que son miembros.
Este nombre debe coincidir por defecto, con la salida de “uname –a” (Esto según RedHat se puede modificar), lo más sencillo es dar a los miembros como nombre, la salida de este comando.


[operador@nodo2 ~]$ uname -a
Linux nodo2.dominio 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386 GNU/Linux


“/etc/cluster/cluster.conf”

……

[clusternode name="nodo1.XXX.XXX.es " votes="1">

……

Configuración Cluster

La configuración del clúster, se hace mediante la aplicación grafica de configuración. (No voy a insertar las capturas ;))
“/usr/sbin/system-config-cluster”

1.- Agregar un Nuevo Nodo (Evidentemente hay que agregar 2)
2.- Agregando un Nuevo dispositivo Fence (Generic Network Block Device)
Este es el dispositivo que nos permite usar tarjetas de red ethernet, para el testeo entre nodos (Fenced)
3.- Agregar el dispositivo fence al Nodo creado anteriormente.
Este dispositivo se a de vincular al nodo que lo tiene fisicamente.
4.- Agregar el dominio del cluster (Esto es mas menos el cluster en si por asi decirlo)
5.- Agregar nodos al dominio
6.- Crear recursos a gestionar por el clúster (Scripts de arranque de servicios, IP Virtuales, Unidades de almacenamiento compartidas ...)
7.- Agregar el script de arranque de mysqld (Que es el servicio que queremos tener en alta disponibilidad)
8.- Agregar IP virtual creada (De este modo la IP sera movida entra nodos a la vez que el servicio, así la IP siempre estará en el nodo que tenga el servicio)
9.- Creamos el servicio, con el que trabajaremos a partir de ahora, el cual incluye todo lo creado anteriormente.



Una vez hecho esto, distribuimos la configuracion a ambos nodos. (La interfaz gráfica nos permite realizar este cambio.), y tras un reboot de los nodos, todo "deberia" y digo deberia, porque nunca las cosas salen a la 1ª, o casi nunca ;)


Procesos de Clúster Suite.
Si todo, está funcionando correctamente la salida del comando “clustat” debería ser la siguiente:


[root@nodo2 ~]# clustat
Member Status: Quorate

Member Name Status
------ ---- ------
nodo1.dominio Online, rgmanager
nodo2.dominio Online, Local, rgmanager

Service Name Owner (Last) State
------- ---- ----- ------ -----
mysql_service nodo2.dominio started



En este resultado se pueden ver, los miembros del clúster, el estado en el que se encuentran, y el estado del servicio/s que gestiona el cluster (started/failed).Si el estado es failed, significa que o bien el Mysqld, no se ha podido arrancar (Error en el servicio, imposibilidad de leer las BD, etc), o bien que la interfaz virtual no está respondiendo, con lo que aun estando online los nodos, el servicio de Mysql no responderá.

Los servicios del cluster arrancados son los siguientes:



[root@nodo2 ~]#chkconfig --list
. . . . .
mysqld 0:desactivado 1:desactivado 2:desactivado 3:desactivado 4:desactivado 5:desactivado 6:desactivado
ccsd 0:desactivado 1:desactivado 2:desactivado 3:activo 4:activo 5:activo 6:desactivado
cman 0:desactivado 1:desactivado 2:desactivado 3:activo 4:activo 5:activo 6:desactivado
fenced 0:desactivado 1:desactivado 2:desactivado 3:activo 4:activo 5:activo 6:desactivado
lock_gulmd 0:desactivado 1:desactivado 2:desactivado 3:activo 4:activo 5:activo 6:desactivado
rgmanager 0:desactivado 1:desactivado 2:activo 3:activo 4:activo 5:activo 6:desactivado
. . . . .

El servicio de Mysql, esta desactivado en todos los niveles de ejecución, ya que debe ser el propio clúster, el encargado de levantarlo en el nodo que este activo.

Los servicios que necesita arrancar el clúster son:

CMAN: Demonio para la administración del clúster.
CCSD: Demonio que hace accesible la configuración del clúster por otros nodos.
FENCED: Demonio para el fencing de dispositivos
LOCK_GULMD: Demonio encargado de parar/bloquear y arrancar/liberar los servicios ofrecidos por el clúster
RGMANAGER: Paquete que contiene entre otras “clustat”

Parada y Arranque manual del servicio de Cluster

En algún momento puede ser necesario, parar completamente el cluster en alguno o ambos nodos, la parada debe realizarse ordenada y de la siguiente manera:

PARADA:
#service rgmanager stop
#service fenced stop
#service ccsd stop

ARRANQUE:
#service rgmanager start
#service fenced start
#service ccsd start

Comandos Interesantes

Mover servicio entre nodos
#clusvadm -r nombre_servicio -m nombre_nodo_destino
Habilitar y Deshabilitar servicio (enable/disable)
#clusvadm -e nombre_servicio
#clusvadm -d nombre_servicio

Notas
En mi caso particular, tuve algunos problemas adicionales, que paso a comentar por encima.

1.- El tema de almacenamiento, ya que no existia la posibilidad de tener un almacenamiento compartido, se realizo en local, añadiendo un script en ambas maquinas, que verificaba cual era el nodo activo y sincronizaba los datos de este a el otro. De este modo la informacion estaba sincronizada cada minuto independientemente de que nodo fuera el activo.

ej.

#!/bin/bash
echo "------------------"
echo "Empieza Sincroniza"
echo "------------------"
echo "nodo2-nodo1"
date

EXISTE=`ps auxw | grep mysqld | grep -v grep`
if [ -z "$EXISTE" ]; then
date>>/etc/local/log_copia_mysql
date>>/etc/local/log_copia_mysql2
rsync -rvztpog --delete --exclude-from=/etc/local/exclude_rsync_mysql -e ssh root@nodo2.dominio:/var/lib/mysql/ /datos/mysql/>>/etc/local/log_copia_mysql
rsync -rvztpog --exclude-from=/etc/local/exclude_rsync_mysql --delete /datos/mysql/ /var/lib/mysql/>>/etc/local/log_copia_mysql2
fi

Se debe excluir de la sincronización el fichero "mysql.sock", ya que no debe existir en el momento de arrancar el servicio, en el otro nodo.