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
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
$ 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
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.