En commençant à regarder le mode cluster de redis à travers une image docker déjà construire https://github.com/Grokzen/docker-redis-cluster, je me suis aperçu que ce n’est pas si transparent. En effaçant, si on essaye d’ajouter une valeur mais que la clé ne correspond au bon noeud, redis ne renvoi pas OK mais plutôt l’indication de ou insérer la donnée:
1 2 3 |
$ redis-cli -p 7000 127.0.0.1:7000> set toto foo (error) MOVED 9738 127.0.0.1:7001 |
Je me suis demandé comment gérer cela dans un programme Java. Est-ce le driver qui va faire le travail ou il faut le gérer à la main.
Si on utilise le driver standard de Jedis, voici ce qu’on obtiens:
1 2 3 4 5 |
Jedis jedis=new Jedis("localhost",7000); jedis.connect(); jedis.set("toto","bar"); String value=jedis.get("toto"); System.out.println("res - "+value); |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Exception in thread "main" redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 9738 127.0.0.1:7001 at redis.clients.jedis.Protocol.processError(Protocol.java:108) at redis.clients.jedis.Protocol.process(Protocol.java:142) at redis.clients.jedis.Protocol.read(Protocol.java:196) at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:288) at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:187) at redis.clients.jedis.Jedis.set(Jedis.java:66) at com.axioconsulting.redis.TestCluster.main(TestCluster.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) |
Heureusement, Jedis propose une classe pour résoudre ce problème (Je n’ai rien trouvé coté JRedis).
1 2 3 4 |
Set jedisClusterNodes=new HashSet(); jedisClusterNodes.add(new HostAndPort("localhost",7000)); jc.set("toto","bar"); String value=jc.get("toto"); System.out.println("res - "+value); |
1 |
res - bar |
Le driver est même capable de récupérer les autres noeuds. Dans l’exemple j’ai indiqué un seul noeud, mais avec le code suivant :
1 2 3 |
for (Map.Entry<string,jedispool> entry:jc.getClusterNodes().entrySet()){ System.out.println(entry.getKey()); } |
on voit bien que le driver a pu récupérer les autres noeuds:
1 2 3 4 5 6 7 |
localhost:7000 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7000 127.0.0.1:7001 |
les sources sont ici
Quelques liens utiles:
– commandes redis cluster
– À la découverte de Redis Cluster 3.0
Ping : Redis Cluster | Veille technologique et autres
Ping : Gestion de session avec un cluster redis | Veille technologique et autres