Redis Cluster 重定向问题 - Moved/Ask重定向

相比于单机redis或使用sentinel来管理的redis主从复制的客户端,Redis cluster的客户端连接更加复杂,需要进行额外的处理。

Moved 重定向

  1. 槽命中:直接返回结果
  2. 槽不命中:即当前键命令所请求的键不在当前请求的节点中,则当前节点会向客户端发送一个Moved 重定向,客户端根据Moved 重定向所包含的内容找到目标节点,再一次发送命令。
    从下面可以看出 php 的槽位9244不在当前节点中,所以会重定向到节点 192.168.2.23:7001中。redis-cli会帮你自动重定向(如果没有集群方式启动,即没加参数 -c,redis-cli不会自动重定向),并且编写程序时,寻找目标节点的逻辑需要交予程序员手动完成。
    cluster keyslot keyName # 得到keyName的槽

ASK 重定向

Ask重定向发生于集群伸缩时,集群伸缩会导致槽迁移,当我们去源节点访问时,此时数据已经可能已经迁移到了目标节点,使用Ask重定向来解决此种情况。

smart客户端

上述两种重定向的机制使得客户端的实现更加复杂,提供了smart客户端(JedisCluster)来减低复杂性,追求更好的性能。客户端内部负责计算/维护键-> 槽 -> 节点映射,用于快速定位目标节点。
实现原理:

  1. 从集群中选取一个可运行节点,使用 cluster slots得到槽和节点的映射关系
  2. 将上述映射关系存到本地,通过映射关系就可以直接对目标节点进行操作(CRC16(key) -> slot -> node),很好地避免了Moved重定向,并为每个节点创建JedisPool
  3. 至此就可以用来进行命令操作

参考资料

[1] https://coding.imooc.com/class/151.html

Author: HB
Link: http://www.huangbin.fun/Redis-Cluster-重定向问题-Moved-Ask重定向.html
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.