Voici le résultat de quelques tests réalisé sur le cluster redis (3.0)
Je suis parti cette image docker https://github.com/Grokzen/docker-redis-cluster
Après un inévitable
make build
l’image est prête à être utilisé. Par défaut, cette image va lancer 3 nœuds masters et 3 nœuds slaves (1 par nœud master).
Lançons la commande
$ make run
Running docker image...
docker run -d -p 7000:7000 -p 7001:7001 -p 7002:7002 -p 7003:7003 -p 7004:7004 -p 7005:7005 -p 7006:7006 -p 7007:7007 --cidfile /tmp/grokzen-redis-cluster.cid -i -t grokzen/redis-cluster
eb5c09e1053fd008e6da693b2bb5a60548cbd41c8c2d8139f9bd89328c255d3b
On peut voir que les ports 7000 à 7005 sont remontés sur le système hôte. Ce sera plus facile pour interroger redis directement.
$ redis-cli -p 7000
127.0.0.1:7000> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
En interrogeant redis, il y a bien 6 nœuds qui constituent le cluster (cluster_known_nodes).
La répartition des clés sautent aux yeux quand on essaye d’insérer une valeur
127.0.0.1:7000> set toto 4
(error) MOVED 9738 127.0.0.1:7001
En lisant ce blog, on voit que la clé de répartition, se calcule comme suit:
HASH_SLOT = CRC16(key) mod 16384
Dans notre cas, key=toto ce qui donne hash_slots=9548
Si on inspecte le cluster, on obtient
$ docker exec -it 4c1589c09148 /bin/bash
root@4c1589c09148:/# /redis/src/redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: c6f94a5f136caf7eccf2d207dc5d6cdccdc44885 127.0.0.1:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: fa1ba98d286a7db6ad6e4f7b37999d79c2671a97 127.0.0.1:7005
slots: (0 slots) slave
replicates 359cc89af7c1654d9fa408ad91abbd1ddc1906f5
M: 63e73580b843d499b665a7385967268528e836e9 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: 359cc89af7c1654d9fa408ad91abbd1ddc1906f5 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: e7520e9f5c6a43fca5bd1dd3e514278fa036fa80 127.0.0.1:7003
slots: (0 slots) slave
replicates c6f94a5f136caf7eccf2d207dc5d6cdccdc44885
S: f86b2c4604bebddec390f032faa7df484d576afe 127.0.0.1:7004
slots: (0 slots) slave
replicates 63e73580b843d499b665a7385967268528e836e9
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
On peut donc voir que notre valeur est contenu entre 5461 et 10922 et donc est géré par le master 63e73580b843d499b665a7385967268528e836e9 soit le l’instance redis sur le port 7001. Ce qui est bien conforme avec l’information fourni par redis.
Que se passe t’il si on arrête un slave:
root@4c1589c09148:/# supervisorctl
redis-1 RUNNING pid 14, uptime 0:09:39
redis-2 RUNNING pid 16, uptime 0:09:39
redis-3 RUNNING pid 15, uptime 0:09:39
redis-4 RUNNING pid 11, uptime 0:09:39
redis-5 RUNNING pid 10, uptime 0:09:39
redis-6 RUNNING pid 13, uptime 0:09:39
redis-7 RUNNING pid 12, uptime 0:09:39
redis-8 RUNNING pid 17, uptime 0:09:39
supervisor> stop redis-6
redis-6: stopped
En relançant la commande
root@4c1589c09148:/# /redis/src/redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7005: [ERR] Sorry, can't connect to node 127.0.0.1:7005
OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: c6f94a5f136caf7eccf2d207dc5d6cdccdc44885 127.0.0.1:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 63e73580b843d499b665a7385967268528e836e9 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: 359cc89af7c1654d9fa408ad91abbd1ddc1906f5 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
0 additional replica(s)
S: e7520e9f5c6a43fca5bd1dd3e514278fa036fa80 127.0.0.1:7003
slots: (0 slots) slave
replicates c6f94a5f136caf7eccf2d207dc5d6cdccdc44885
S: f86b2c4604bebddec390f032faa7df484d576afe 127.0.0.1:7004
slots: (0 slots) slave
replicates 63e73580b843d499b665a7385967268528e836e9
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
On voit bien l’erreur de connexion à l’instance sur le port 7005 mais cela n’a pas d’incidence sur la santé du cluster.
Que se passe t’il si on arrête un master.
supervisor> stop redis-2
redis-2: stopped
root@4c1589c09148:/# /redis/src/redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7001: [ERR] Sorry, can't connect to node 127.0.0.1:7001
OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
*** WARNING: 127.0.0.1:7004 claims to be slave of unknown node ID 63e73580b843d499b665a7385967268528e836e9.
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: c6f94a5f136caf7eccf2d207dc5d6cdccdc44885 127.0.0.1:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: fa1ba98d286a7db6ad6e4f7b37999d79c2671a97 127.0.0.1:7005
slots: (0 slots) slave
replicates 359cc89af7c1654d9fa408ad91abbd1ddc1906f5
M: 359cc89af7c1654d9fa408ad91abbd1ddc1906f5 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: e7520e9f5c6a43fca5bd1dd3e514278fa036fa80 127.0.0.1:7003
slots: (0 slots) slave
replicates c6f94a5f136caf7eccf2d207dc5d6cdccdc44885
S: f86b2c4604bebddec390f032faa7df484d576afe 127.0.0.1:7004
slots: (0 slots) slave
replicates 63e73580b843d499b665a7385967268528e836e9
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
Le cluster voit bien le problème de connexion à l’instance défaillante.
il voit aussi qu’il y a un slave qui n’a pas de master. A la dernière ligne, on voit qu’il y a un problème de cohérence sur le cluster car tous les slots de répartition ne sont pas couverts par le cluster
Mais cela est corrigé quand le slave devient master:
root@4c1589c09148:/# /redis/src/redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: c6f94a5f136caf7eccf2d207dc5d6cdccdc44885 127.0.0.1:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: fa1ba98d286a7db6ad6e4f7b37999d79c2671a97 127.0.0.1:7005
slots: (0 slots) slave
replicates 359cc89af7c1654d9fa408ad91abbd1ddc1906f5
M: 359cc89af7c1654d9fa408ad91abbd1ddc1906f5 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: e7520e9f5c6a43fca5bd1dd3e514278fa036fa80 127.0.0.1:7003
slots: (0 slots) slave
replicates c6f94a5f136caf7eccf2d207dc5d6cdccdc44885
M: f86b2c4604bebddec390f032faa7df484d576afe 127.0.0.1:7004
slots:5461-10922 (5462 slots) master
0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
J’ai modifié le programme Java initié dans le précédent article et je mesure à 6s, le temps pour que le cluster soit de nouveaux opérationnels;
23:37:19.CEST / res - bar
23:37:20.CEST / Too many Cluster redirections?
23:37:21.CEST / Too many Cluster redirections?
23:37:22.CEST / Too many Cluster redirections?
23:37:23.CEST / Too many Cluster redirections?
23:37:24.CEST / Too many Cluster redirections?
23:37:25.CEST / CLUSTERDOWN The cluster is down
23:37:26.CEST / res - bar
Il est peut être possible de jouer sur le paramétrage pour descendre ce temps, mais je n’ai pas encore trouvé comment.
On voit bien ici le problème lorsque que les données ne soit pas répliquées entre les différents masters. Lorsqu’un master est absent, il y a un « petit » laps de temps ou les données ne sont pas connues.