假设,当前redis集群只有2个节点 node-A 和 node-B,总共有3个slot, 其和节点的对应关系如图, client 会将其缓存一个映射map
现在要扩容新增一个节点 node-3, 并把 slot3 的数据迁移到 node-3,如下图
在 slot-3 迁移结束前,crc16(key) % 16384 = 3 的 key, 可能还在 node-B, 也可能迁移到 node-C 了
先看看 key 迁移过程中,redis cluster 节点会返回什么响应
假设slot-3 共有 key1,key2,key3,key4,key5 5个key,当前 key1、key2、key3 已经迁移到 node-C 了, 如下图:
正常返回
(1) 由于key1已经迁移到 node-C了, 这个时候 node-B 会返回 -ASK 重定向到 node-C
(2) 接着需要先向 node-C 发送一个 ASKING 指令,然后才能从 node-C 获取到 key1 的值
(3) 如果直接向 node-C 发送 get key1 的话,会收到 moved 响应,让你去 node-B 执行;所以此时更新客户端 node映射缓存是没有用的
在slot迁移过程中,任然向 slot 原节点发送命令,每次收到 ASK 后,先发送 ASKING 指令临时重定向到新节点,再正常执行命令, 此时不需要更新 客户端slot-node 映射缓存
参考:https://redis.io/topics/cluster-spec#ask-redirection