En este escenario vamos a estar trabajando con Gluster 3.5.2 (not production ready yet, but good enough :P) sobre CentOS 6.5.
Creando un volumen con replica 2
Para empezar necesitamos crear un volumen. En este caso creamos un volumen con réplica 2 de la siguiente manera:
[root@gluster-test-1 ~]# gluster vol create volumen_prueba replica 2 gluster-test-1:/ladrillos/l1/l gluster-test-2:/ladrillos/l1/l
volume create: volumen_prueba: success: please start the volume to access data
[root@gluster-test-1 ~]# gluster vol start volumen_prueba
volume start: volumen_prueba: success
[root@gluster-test-1 ~]#
Una vez creado e iniciado vemos su estado e información
[root@gluster-test-1 ~]# gluster vol status volumen_prueba
Status of volume: volumen_prueba
Gluster process Port Online Pid
------------------------------------------------------------------------------
Brick gluster-test-1:/ladrillos/l1/l 49159 Y 11717
Brick gluster-test-2:/ladrillos/l1/l 49159 Y 12102
NFS Server on localhost N/A N N/A
Self-heal Daemon on localhost N/A Y 11731
NFS Server on gluster-test-3 N/A N N/A
Self-heal Daemon on gluster-test-3 N/A Y 11929
NFS Server on gluster-test-2 N/A N N/A
Self-heal Daemon on gluster-test-2 N/A Y 12120
Task Status of Volume volumen_prueba
------------------------------------------------------------------------------
There are no active volume tasks
[root@gluster-test-1 ~]# gluster vol info volumen_prueba
Volume Name: volumen_prueba
Type: Replicate
Volume ID: 1197881d-ce2a-4f64-af17-53e5529b691c
Status: Started
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: gluster-test-1:/ladrillos/l1/l
Brick2: gluster-test-2:/ladrillos/l1/l
[root@gluster-test-1 ~]#
Ahora que vemos que todo se encuentra bien montamos el volumen desde la máquina cliente:
[root@gluster-client-1 ~]# mount.glusterfs gluster-test-1:/volumen_prueba /mnt/gluster_vol
[root@gluster-client-1 ~]#
Dado que el montaje fue exitoso vemos los logs en /var/log/gluster/mnt-gluster_vol.log y encontramos la definición del volumen (todos estos translators y demás valores se cargan por defecto):
Final graph:
+------------------------------------------------------------------------------+
1: volume volumen_prueba-client-0
2: type protocol/client
3: option remote-host gluster-test-1
4: option remote-subvolume /ladrillos/l1/l
5: option transport-type socket
6: option send-gids true
7: end-volume
8:
9: volume volumen_prueba-client-1
10: type protocol/client
11: option remote-host gluster-test-2
12: option remote-subvolume /ladrillos/l1/l
13: option transport-type socket
14: option send-gids true
15: end-volume
16:
17: volume volumen_prueba-replicate-0
18: type cluster/replicate
19: subvolumes volumen_prueba-client-0 volumen_prueba-client-1
20: end-volume
21:
22: volume volumen_prueba-dht
23: type cluster/distribute
24: subvolumes volumen_prueba-replicate-0
25: end-volume
26:
27: volume volumen_prueba-write-behind
28: type performance/write-behind
29: subvolumes volumen_prueba-dht
30: end-volume
31:
32: volume volumen_prueba-read-ahead
33: type performance/read-ahead
34: subvolumes volumen_prueba-write-behind
35: end-volume
36:
37: volume volumen_prueba-io-cache
38: type performance/io-cache
39: subvolumes volumen_prueba-read-ahead
40: end-volume
41:
42: volume volumen_prueba-quick-read
43: type performance/quick-read
44: subvolumes volumen_prueba-io-cache
45: end-volume
46:
47: volume volumen_prueba-open-behind
48: type performance/open-behind
49: subvolumes volumen_prueba-quick-read
50: end-volume
51:
52: volume volumen_prueba-md-cache
53: type performance/md-cache
54: subvolumes volumen_prueba-open-behind
55: end-volume
56:
57: volume volumen_prueba
58: type debug/io-stats
59: option latency-measurement off
60: option count-fop-hits off
61: subvolumes volumen_prueba-md-cache
62: end-volume
63:
+------------------------------------------------------------------------------+
Las líneas 37 a 40 hacen referencia a la configuración del performance/IO-cache translator, el cuál se encarga de definir la configuración del cache del volumen. Como vemos no hay demasiado configurado dado que aún se encuentra todo por defecto. Según la documentación oficial el tamaño default del cache es de 32Mbytes y un tiempo de expiración de 1 segundo.
Algunos de los parámetros que podremos controlar desde aquí son:
- cache-size: espacio asignado a cache
- cache-timeout: tiempo de expiración de los objetos en cache
- priority: permite asignar prioridades a distintos tipos de archivos para el uso de cache
- cache-max-file-size: tamaño máximo de archivo que se puede almacenar en cache
- cache-min-file-size: tamaño mínimo de archivo que se puede almacenar en cache
Probando los default settings:
Ahora que montamos el archivo vamos a probar la configuración por defecto con que se arman los volúmenes en gluster.
Primero escribimos un archivo de 25Mbytes en el directorio montado:
[root@gluster-client-1 ~]# dd if=/dev/zero of=/mnt/gluster_vol/25MB bs=1M count=25
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0286961 s, 914 MB/s
[root@gluster-client-1 ~]# ll -h /mnt/gluster_vol/
total 25M
-rw-r--r--. 1 root root 25M ago 24 20:54 25MB
[root@gluster-client-1 ~]#
Ahora lo leeremos con intervalos de 10 segundos limpiando los bufferes del sistema entre cada operación:
[root@gluster-client-1 ~]# for i in 1 2 3 4 5; do echo 3 > /proc/sys/vm/drop_caches; dd of=/dev/null if=/mnt/gluster_vol/25MB bs=1M; date; sleep 10;done
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,271792 s, 96,5 MB/s
dom ago 24 21:20:12 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0568677 s, 461 MB/s
dom ago 24 21:20:22 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0402717 s, 651 MB/s
dom ago 24 21:20:32 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0392092 s, 669 MB/s
dom ago 24 21:20:43 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0420014 s, 624 MB/s
dom ago 24 21:20:53 ART 2014
[root@gluster-client-1 ~]#
Interesante! La primer lectura demora 0.27 segundos, mientras que las 4 siguientes demoran entre 0.03 y 0.05! Claramente se trata de la intervención de la cache. Podría parecer confuso por los 10 segundos que esperamos entre lectura y lectura, pero la documentación define cache-timeout como un tiempo de expiración que fuerza una de re-validación, así que este es un comportamiento esperable. Probablemente estos 10 segundos de espera hubiesen sido demasiado en un entorno de mayor uso del cache.
Ahora corremos la misma prueba pero removiendo el tiempo de espera de 10 segundos:
[root@gluster-client-1 ~]# for i in 1 2 3 4 5; do echo 3 > /proc/sys/vm/drop_caches; dd of=/dev/null if=/mnt/gluster_vol/25MB bs=1M; date; done
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0485229 s, 540 MB/s
dom ago 24 21:25:18 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0471389 s, 556 MB/s
dom ago 24 21:25:18 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0360902 s, 726 MB/s
dom ago 24 21:25:18 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0359891 s, 728 MB/s
dom ago 24 21:25:18 ART 2014
25+0 records in
25+0 records out
26214400 bytes (26 MB) copied, 0,0355376 s, 738 MB/s
dom ago 24 21:25:18 ART 2014
[root@gluster-client-1 ~]#
Podemos ver que los tiempos no son demasiado diferentes a los que obtuvimos anteriormente.
Qué pasaría con un archivo mayor a 32Mbytes...? Escribimos un archivo de 128Mbytes para ver qué sucede:
[root@gluster-client-1 ~]# dd if=/dev/zero of=/mnt/gluster_vol/128MB bs=1M count=128
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 2,403 s, 55,9 MB/s
[root@gluster-client-1 ~]# ll -h /mnt/gluster_vol/
total 153M
-rw-r--r--. 1 root root 128M ago 24 21:27 128MB
-rw-r--r--. 1 root root 25M ago 24 21:19 25MB
[root@gluster-client-1 ~]#
Ahora lo leemos:
[root@gluster-client-1 ~]# for i in 1 2 3 4 5; do echo 3 > /proc/sys/vm/drop_caches; dd of=/dev/null if=/mnt/gluster_vol/128MB bs=1M; date; done
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,95299 s, 68,7 MB/s
dom ago 24 21:29:09 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,95518 s, 68,6 MB/s
dom ago 24 21:29:11 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,96224 s, 68,4 MB/s
dom ago 24 21:29:13 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,94886 s, 68,9 MB/s
dom ago 24 21:29:15 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,98702 s, 67,5 MB/s
dom ago 24 21:29:17 ART 2014
[root@gluster-client-1 ~]#
En este caso vemos claramente que estamos teniendo velocidades de lectura muy bajas, lo que nos da la pauta de que no estamos utilizando la cache.
Modificando la configuración de cache:
Ahora vamos a aumentar nuestra capacidad de cache para lograr una buena velocidad de lectura en el caso del archivo de 128Mbytes. Seteamos la cache a 256Mbytes de la siguiente manera:
[root@gluster-test-1 ~]# gluster vol set volumen_prueba performance.cache-size 256MB
volume set: success
[root@gluster-test-1 ~]# gluster vol info volumen_prueba
Volume Name: volumen_prueba
Type: Replicate
Volume ID: 1197881d-ce2a-4f64-af17-53e5529b691c
Status: Started
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: gluster-test-1:/ladrillos/l1/l
Brick2: gluster-test-2:/ladrillos/l1/l
Options Reconfigured:
performance.cache-size: 256MB
[root@gluster-test-1 ~]#
Podríamos pensar que no sucedió nada, pero...
[root@gluster-client-1 ~]# for i in 1 2 3 4 5; do echo 3 > /proc/sys/vm/drop_caches; dd of=/dev/null if=/mnt/gluster_vol/128MB bs=1M; date; done
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,59836 s, 84,0 MB/s
dom ago 24 21:34:25 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1,26796 s, 106 MB/s
dom ago 24 21:34:26 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 0,159935 s, 839 MB/s
dom ago 24 21:34:26 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 0,152958 s, 877 MB/s
dom ago 24 21:34:27 ART 2014
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 0,164556 s, 816 MB/s
dom ago 24 21:34:27 ART 2014
[root@gluster-client-1 ~]#
Sin necesidad de reiniciar absolútamente nada, ni de desmontar el volumen, vemos como gluster fue capaz de reconocer el aumento del tamaño de cache y permitirnos leer el archivo de 128Mbytes hasta mas de 10 veces mas rápido!!!
El resto es cuento, solo hay que ponerse a jugar con los valores para obtener la política de cache que uno quiere.
Dónde se almacena la cache?
Hice un par de preguntas al respecto en la lista de usuarios de gluster, dado que no me quedaba del todo claro dónde se almacena la cache. Según la documentación el translator performance/io-cache puede encontrarse presente tanto en el servidor como en el cliente con objetivos distintos.
- Estando en el servidor permite compartir la cache con varios clientes de manera simultánea.
- Estando en el cliente permite ahorrar ancho de banda y CPU (del servidor).