Mostrando entradas con la etiqueta ha. Mostrar todas las entradas
Mostrando entradas con la etiqueta ha. Mostrar todas las entradas

miércoles, 12 de noviembre de 2014

Gluster: usando quotas

Una de las funcionalidades de gluster que me resultó de gran utilidad en estos días dada la escasez de espacio son las quotas. Básicamente las quotas nos permiten asignar límites de uso de espacio a directorios dentro de los volúmenes de gluster.

Supongamos que tenemos 2 aplicaciones aplicacion1 y aplicacion2 que tienen acceso a directorios homónimos dentro de un volumen gluster replicado llamado contenedor. A continuación vemos el volumen en cuestión:


[root@gluster-server-2 ~]# gluster vol info

Volume Name: contenedor
Type: Replicate
Volume ID: 3933514f-f5a4-4260-9d40-964c6cc44b59
Status: Started
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: 172.16.47.15:/mnt/1
Brick2: 172.16.47.16:/mnt/1
[root@gluster-server-2 ~]# 

El primer paso para utilizar quotas es habilitarlas en el volumen:

[root@gluster-server-2 ~]# gluster vol quota contenedor enable
Enabling quota has been successful
[root@gluster-server-2 ~]# 

Verificamos que la operación se haya concretado correctamente:

[root@gluster-server-2 ~]# gluster vol info
 
Volume Name: contenedor
Type: Replicate
Volume ID: 3933514f-f5a4-4260-9d40-964c6cc44b59
Status: Started
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: 172.16.47.15:/mnt/1
Brick2: 172.16.47.16:/mnt/1
Options Reconfigured:
features.quota: on
[root@gluster-server-2 ~]# 

Ahora que las quotas están habilitadas podemos configurarlas. En este caso cofiguramos una quota de 1GB para el directorio aplicacion1 y 512MB para el directorio aplicacion2:

[root@gluster-server-2 ~]# gluster vol quota contenedor limit-usage /aplicacion1 1024MB
limit set on /aplicacion1
[root@gluster-server-2 ~]# gluster vol quota contenedor limit-usage /aplicacion2 512MB
limit set on /aplicacion2
[root@gluster-server-2 ~]# 

Corroboramos que se hayan aplicado las quotas:

[root@gluster-server-2 ~]# gluster vol info
 
Volume Name: contenedor
Type: Replicate
Volume ID: 3933514f-f5a4-4260-9d40-964c6cc44b59
Status: Started
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: 172.16.47.15:/mnt/1
Brick2: 172.16.47.16:/mnt/1
Options Reconfigured:
features.limit-usage: /aplicacion1:1024MB,/aplicacion2:512MB
features.quota: on
[root@gluster-server-2 ~]# 

Ahora probamos las cuotas escribiendo en los directorios desde el cliente que monta el volumen. El volumen lo montamos en /mnt:

[root@gluster-client ~]# mount
/dev/vda1 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw,rootcontext="system_u:object_r:tmpfs_t:s0")
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
172.16.47.15:/contenedor on /mnt type fuse.glusterfs (rw,default_permissions,allow_other,max_read=131072)
[root@gluster-client ~]# ls /mnt/
aplicacion1  aplicacion2
[root@gluster-client ~]# 

Primero escribimos en ambos directorios hasta poco antes del límite:

[root@gluster-client ~]# dd if=/dev/zero of=/mnt/aplicacion1/archivo_grande bs=1M count=1020
1020+0 records in
1020+0 records out
1069547520 bytes (1.1 GB) copied, 32.5717 s, 32.8 MB/s
[root@gluster-client ~]# dd if=/dev/zero of=/mnt/aplicacion2/archivo_grande bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 14.0041 s, 37.4 MB/s
[root@gluster-client ~]# 

Vemos cuánto escribimos en cada directorio:

[root@gluster-client ~]# du -sch /mnt/*
1020M /mnt/aplicacion1
500M /mnt/aplicacion2
1.5G total
[root@gluster-client ~]# 

De momento nos mantuvimos por debajo de los límites definidos en las cuotas, por eso no tuvimos problema alguno. Podemos verificar el estado de las cuotas fijadas de la siguiente manera:

[root@gluster-server-2 ~]# gluster vol quota contenedor list
path  limit_set     size
----------------------------------------------------------------------------------
/aplicacion1             1024MB             1020.0MB
/aplicacion2              512MB              500.0MB
[root@gluster-server-2 ~]# 

Ahora ponemos a prueba el control escribiendo mas allá de lo permitido con un nuevo archivo:

[root@gluster-client ~]# dd if=/dev/zero of=/mnt/aplicacion1/archivo_chico bs=1M count=100
dd: escribiendo «/mnt/aplicacion1/archivo_chico»: Se ha excedido la cuota de disco
6+0 records in
5+0 records out
5898240 bytes (5.9 MB) copied, 0.141132 s, 41.8 MB/s
[root@gluster-client ~]# dd if=/dev/zero of=/mnt/aplicacion2/archivo_chico bs=1M count=100
dd: escribiendo «/mnt/aplicacion2/archivo_chico»: Se ha excedido la cuota de disco
dd: cerrando el fichero de salida «/mnt/aplicacion2/archivo_chico»: Se ha excedido la cuota de disco
[root@gluster-client ~]# 

JA! No pudimos escribir demasiado, alcanzamos los límites fijados por las cuotas:

[root@gluster-client ~]# du -sch /mnt/*
1.1G /mnt/aplicacion1
513M /mnt/aplicacion2
1.6G total
[root@gluster-client ~]# 

también lo podemos ver desde gluster:

[root@gluster-server-2 ~]# gluster vol quota contenedor list
path  limit_set     size
----------------------------------------------------------------------------------
/aplicacion1             1024MB                1.0GB
/aplicacion2              512MB              512.5MB
[root@gluster-server-2 ~]# 

Una vez alcanzada la cuota ni siquiera se nos permite crear nuevos archivos o directorios:

[root@gluster-client ~]# touch /mnt/aplicacion1/a
touch: no se puede efectuar `touch' sobre «/mnt/aplicacion1/a»: Se ha excedido la cuota de disco
[root@gluster-client ~]# touch /mnt/aplicacion2/a
touch: no se puede efectuar `touch' sobre «/mnt/aplicacion2/a»: Se ha excedido la cuota de disco
[root@gluster-client ~]# mkdir /mnt/aplicacion1/b
mkdir: no se puede crear el directorio «/mnt/aplicacion1/b»: Se ha excedido la cuota de disco
[root@gluster-client ~]# mkdir /mnt/aplicacion2/b
mkdir: no se puede crear el directorio «/mnt/aplicacion2/b»: Se ha excedido la cuota de disco
[root@gluster-client ~]# 

Las cuotas pueden ser aplicadas a sub directorios también, y un punto a considerar es que se trata de cuotas duras, es decir que NO se pueden sobrepasar.

viernes, 8 de agosto de 2014

Gluster: graficando mi Gluster II

Luego de comentar la herramienta en la lista oficial de usuarios de gluster gluster-users@gluster.org, me recomendaron hacerla un proyecto oficial de la comunidad y me pareció una buena idea. Así es como nació GlusterGraph. Desde el link podrán acceder tanto a las fuentes de la herramienta como a una pequeña wiki que describe cómo utilizarla en uno pocos pasos.

Les dejo un ejemplo de ejecución para mas o menos cerrar la idea:

  • Clonar el repositorio:
jpavlik@corrientes:~/Escritorio/devnull/borrar$ git clone git://forge.gluster.org/glustergraph/glustergraph.git
Clonar en «glustergraph»...
remote: Counting objects: 73, done.
remote: Compressing objects: 100% (62/62), done.
remote: Total 73 (delta 20), reused 0 (delta 0)
Receiving objects: 100% (73/73), 58.33 KiB, done.
Resolving deltas: 100% (20/20), done.

  • Ubicar el archivo ejecutable:
jpavlik@corrientes:~/Escritorio/devnull/borrar$ ls glustergraph/GlusterGraph/ExecJar/
glustergraph.jar
jpavlik@corrientes:~/Escritorio/devnull/borrar$ 
  • Ejecutarlo pasando como entrada gluster volume info y redireccionando la salida a out.dot (debería ver algo como lo siguiente):
jpavlik@corrientes:~/Escritorio/devnull/borrar$ gluster volume info | java -jar glustergraph/GlusterGraph/ExecJar/glustergraph.jar > out.dot
GlusterGraph v0.1

Loading all volumes

New volume found: fernanda-02
New brick found: gfsc-nodo03:/ladrillos/l1                                                                                                                                                      
New node found: gfsc-nodo03
New brick found: gfsc-nodo03:/ladrillos/l3                                                                                                                                                      
New volume found: fernanda
New brick found: gfsc-nodo04:/ladrillos/l1
New node found: gfsc-nodo04
New brick found: gfsc-nodo01:/ladrillos/l1
New node found: gfsc-nodo01
New brick found: gfsc-nodo04:/ladrillos/l2
New brick found: gfsc-nodo01:/ladrillos/l2
New brick found: gfsc-nodo04:/ladrillos/l3
New brick found: gfsc-nodo02:/ladrillos/l1
New node found: gfsc-nodo02
New brick found: gfsc-nodo03:/ladrillos/l2
New brick found: gfsc-nodo02:/ladrillos/l2
New brick found: gfsc-nodo04:/ladrillos/l5
New brick found: gfsc-nodo02:/ladrillos/l3
New brick found: gfsc-nodo01:/ladrillos/l3
New brick found: gfsc-nodo04:/ladrillos/l4
jpavlik@corrientes:~/Escritorio/devnull/borrar$ 
  • Ahora graficamos el archivo con dot:
jpavlik@corrientes:~/Escritorio/devnull/borrar$ dot -Tpng out.dot > out.png
jpavlik@corrientes:~/Escritorio/devnull/borrar$ ls out*
out.dot  out.png
jpavlik@corrientes:~/Escritorio/devnull/borrar$ 
  • Abrimos la imagen:

sábado, 18 de enero de 2014

Memcached replicado en Ubuntu 12.04 LTS (haciendo el paquete)

No estaba seguro si ameritaba o no un nuevo post, pero ante la duda así será. La idea de este post es en lugar de hacer una compilación clásica configure && make && make install, crear un paquete que luego podamos transportar sencillamente e instalar en otros servidores similares. Agradezco de antemano a Tomás por la colaboración y la paciencia!

Los pasos que hay que seguir son similares a los del post anterior, (de hecho los pasos del 1 al 4 no cambian, ver http://viviendolared.blogspot.com.ar/2014/01/memcached-replicado-en-ubuntu-1204-lts.html), y por lo tanto comenzaremos a partir del punto 5.

5-Cambios en las reglas de compilación
Para poder crear exitosamente nuestro paquete de memcached con replicación debemos indicarle a dpkg-buildpackage que esta opción debe estar activa y esto lo logramos editando el archivo debian/rules en el directorio de código de fuente obtenido previamente. Es necesario agregar la linea --enable-replication como se indica a continuación (NOTESE la \ al final de la linea previa)


...
config.status: configure
        dh_testdir
        CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) \
                                       --build=$(DEB_BUILD_GNU_TYPE) \
                                       --prefix=/usr \
                                       --mandir=\$${prefix}/share/man \
                                       --infodir=\$${prefix}/share/info \
                                       --enable-replication


6-Generando el .deb
Ahora nos ubicamos dentro del directorio del código de fuente y creamos el paquete.


root@memcached1:~/memcached-1.4.13# dpkg-buildpackage -us -uc -nc
...
...
dpkg-buildpackage: binary and diff upload (original source NOT included)

Si vemos el directorio superior encontramos el archivo memcached_1.4.13-0ubuntu2.1_amd64.deb que se acaba de generar.

root@memcached1:~/memcached-1.4.13# ls ..
memcached-1.4.13                     memcached_1.4.13-0ubuntu2.1.dsc            memcached_1.4.13-0ubuntu2.1_amd64.deb  repcached-2.3.1-1.4.13.patch
memcached_1.4.13-0ubuntu2.1.diff.gz  memcached_1.4.13-0ubuntu2.1_amd64.changes  memcached_1.4.13.orig.tar.gz           tools
root@memcached1:~/memcached-1.4.13#

7-Instalamos el paquete
Ahora sencillamente instalamos el paquete con dpkg -i


root@memcached1:~# dpkg -i memcached_1.4.13-0ubuntu2.1_amd64.deb 
Selecting previously unselected package memcached.
(Reading database ... 75101 files and directories currently installed.)
Unpacking memcached (from memcached_1.4.13-0ubuntu2.1_amd64.deb) ...
Setting up memcached (1.4.13-0ubuntu2.1) ...
Starting memcached: memcached.
Processing triggers for ureadahead ...
Processing triggers for man-db ...
root@memcached1:~#

Y listo, ahora solo nos queda editar el archivo de configuración /etc/memcached.conf con las opciones correspondientes a nuestro entorno y ya tenemos nuevamente memcached replicado de manera mas sencilla y hasta me atrevería a decir mas limpia.
Este mismo paquete generado podemos copiarlo en el servidor memcached2 e instalar memcached con replicación simplemente haciendo dpkg -i memcached_1.4.13-0ubuntu2.1_amd64.deb simpático, no :D?

jueves, 16 de enero de 2014

Memcached replicado en Ubuntu 12.04 LTS

Como parte del despliegue de OpenStack que estamos haciendo hace ya unos meses en el trabajo surgió la necesidad de contar con alta disponibilidad en el servicio de cache provisto por memcached (Memcached es una sencilla pero muy poderosa solución de cache en memoria, utilizada por grandes personajes de Internet como Wikipedia, Youtube, Twitter, etc). En OpenStack, memcached se utiliza principalmente para proveer agilidad a la interfaz web Horizon.

Los siguientes 6 pasos deben ser aplicados a ambos servidores (cabe aclarar que este método solo permite 2 servidores, es una restricción del propio repcached).

1-Preparar el entorno
Debemos instalar una serie de paquetes para poder compilar nuestra propia versión de memcached con replicación.

root@memcached1:~/# apt-get build-dep memcached

2-Obtener el código de fuente
La forma mas sencilla de obtener el código de fuente es:

root@memcached1:~/# apt-get source memcached

3. Obteniendo el código de repcached
Repcached es un parche que aplicamos sobre el código de memcached, que nos da la capacidad de poder replicar nuestra cache en 2 servidores. Obtener el código de https://github.com/usecide/repcached/blob/master/repcached-2.3.1-1.4.13.patch

root@memcached2:~# wget https://raw.github.com/usecide/repcached/master/repcached-2.3.1-1.4.13.patch

4-Aplicar el parche

root@memcached1:~/# mv repcached-2.3.1-1.4.13.patch memcached-1.4.13/
root@memcached1:~/# cd memcached-1.4.13/
root@memcached1:~/memcached-1.4.13# patch -p1 -i repcached-2.3.1-1.4.13.patch

5-Configurar, Compilar e Instalar

root@memcached1:~/memcached-1.4.13# ./configure –enable-replication
root@memcached1:~/memcached-1.4.13# make
root@memcached1:~/memcached-1.4.13# make install

"make install", si todo sale bien nos dejará nuestra versión de memcached en el directorio /usr/local/bin/.

6-Puesta en marcha
Necesitamos una serie de retoques para poner a punto nuestro memcached con replicación.
Primero debemos crear un script de arranque que nos permite iniciar/reiniciar/detener el servicio a gusto y placer y ubicarlo en /etc/init.d/ con el nombre memcachedrep, el archivo se puede obtener de http://pastebin.com/WfxPV81W ; luego es necesario hacer el archivo ejecutable:

root@memcached1:~/memcached-1.4.13# chmod +x /etc/init.d/memcachedrep

Como segundo paso creamos un archivo de configuración para el servicio en /etc/default/ con nombre memcachedrep y escribimos la siguiente linea en él:


DAEMON_ARGS="-m 256 -p 11211 -u root -P /var/run/memcachedrep.pid -d -v -t 4 -x 172.16.254.118"

Siendo:
-m 256: utilizar 256Mb de memoria para almacen.
-p 11211: escucha peticiones en el puerto 11211, TCP y UDP
-u root: usuario con el que ejecutará el demonio
-P /var/run/memcachedrep.pid: archivo que contendrá el PID del demonio en ejecución
-d: lanza memcached en modo demonio
-v: modo verborrágico, nos permitirá ver advertencias y errores en la ejecución
-t 4: cantidad de hilos que utilizará memcached   
-x 172.16.254.118: este parámetro es propio del parche repcached e indica quien es el servidor con el que se replicará. En nuestro caso los servidores son 172.16.254.117 (memcached1) y 172.16.254.118 (memcached2). Por defecto los servidores se sincronizaran utilizando una conexión dedicada en el puerto 11212.

Por último agregamos memcachedrep a los servicios del sistema:

root@memcached1:~/memcached-1.4.13# update-rc.d memcachedrep defaults

7-Probando la replicación
Bien, ahora llega la parte divertida, ya tenemos ambos servidores listos para correr nuestra versión de memcached con replicación. 


Iniciamos memcachedrep en el nodo memcached1:


root@memcached1:~# service memcachedrep start
root@memcached1:~# replication: connect (peer=172.16.254.118:11212)
replication: marugoto copying
replication: close
replication: listen
root@memcached1:~# 


podemos ver que la replicación se encuentra "close", esto se debe a que la instancia de memcached que lanzamos no pudo conectarse con el otro nodo (172.16.254.118 memcached2). Podriamos utilizar solamente este nodo, en caso de que el otro no funcione.
Ahora iniciamos el segundo nodo:

root@memcached2:~# replication: connect (peer=172.16.254.117:11212)
replication: marugoto copying
replication: start

root@memcached2:~#  

Perfecto, ambas instancias están levantadas y conectadas. Podemos verificar que se han conectado con el siguiente comando:


root@memcached2:~# netstat -ntap|grep ESTA|grep 11212
tcp        0      0 172.16.254.118:35734    172.16.254.117:11212    ESTABLISHED 31503/memcached 
root@memcached2:~# 

También podemos ver en el nodo memcached1 un mensaje indicandolo:


root@memcached1:~# replication: accept


Ahora viene la prueba de fuego, cargamos un dato en el nodo memcached1 y lo buscamos en memcached2:

root@memcached1:~# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set juan 0 0 4
jose
STORED
quit
Connection closed by foreign host.
root@memcached1:~# 

root@memcached2:~# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get juan
VALUE juan 0 4
jose
END
quit
Connection closed by foreign host.
root@memcached2:~# 

Y así podemos apreciar el efecto de la replicación. Si sumada a la replicación, ubicamos delante de ambos servidores un balanceador TCP como haproxy logramos sencillamente un mecanismo de cache con alta disponibilidad y balanceo de carga.

Lamentablemente el proyecto repcached se encuentra en un estado no muy activo y por lo tanto dificilmente haya novedades al respecto, pero sin lugar a dudas es una buena opción para lograr estos objetivos.