10.5.1 请求重定向

在集群模式下, Redis 接收任何键相关命令时首先计算键对应的, 再根据槽找出所对应的节点, 如果节点是自身, 则处理键命令; 否则回复 MOVED 重定向错误, 通知客户端请求正确的节点。这个过程称为 MOVED 重定向:

image.png

可以借助 cluster keyslot {key} 命令返回 key 所对应的槽:

  1. 127.0.0.1:6379> cluster keyslot key:test:1

回复 MOVED {slot} {ip} {port} 格式重定向信息:

image.png

image.png

1. 计算槽

crc16(key)&16383

  • key 中如果包含 {} , 则只计算其中的部分. hash_tag
  • hash_tag 用于 Redis IO 优化, 使不同 key 映射到相同 slot 中

2. 槽节点查找

集群内通过消息交换每个节点都会知道所有节点的槽信息, 内部保存在 clusterState 结构中:

image.png

slots 数组表示槽和节点对应关系, 实现请求重定向伪代码如下:

image.png

Dummy (傀儡) 客户端:

  • 需要 MOVED 重定向机制, 增加 IO 开销

10.5.2 Smart 客户端

1. smart 客户端原理

Smart 客户端通过在内部维护 slot→node 的映射关系, 本地就可实现键到节点的查找, 从而保证 IO 效率的最大化, 而 MOVED 重定向负责协助 Smart 客户端更新 slot→node 映射。

后续跳过.

10.5.3 ASK 重定向

1. 客户端 ASK 重定向流程

当一个 slot 数据从源节点迁移到目标节点时, 期间可能出现一部分数据在源节点, 而另一部分在目标节点:

image.png

ASK 重定向整体流程:

image.png

ask 与 moved 重定向区别:

ASK 重定向说明集群正在进行 slot 数据迁移, 客户端无法知道什么时候迁移完成, 因此只能是临时性的重定向, 客户端不会更新 slots 缓存。但是 MOVED 重定向说明键对应的槽已经明确指定到新的节点, 因此需要更新 slots 缓存。

2. 节点内部处理

为了支持 ASK 重定向, 源节点和目标节点在内部的 clusterState 结构中维护当前正在迁移的槽信息, 用于识别槽迁移情况:

image.png

处理过程:

  • 如果键所在的槽由当前节点负责, 但键不存在则查找 migrating_slots_to 数组查看槽是否正在迁出, 如果是返回 ASK 重定向
  • 如果客户端发送 asking 命令打开了 CLIENT_ASKING 标识, 则该客户端下次发送键命令时查找 importing_slots_from 数组获取 clusterNode, 如果指向自身则执行命令
  • 需要注意的是, asking 命令是一次性命令, 每次执行完后客户端标识都会修改回原状态, 因此每次客户端接收到 ASK 重定向后都需要发送 asking 命令
  • 批量操作。ASK 重定向对单键命令支持得很完善, 但是, 在开发中我们经常使用批量操作, 如 mget 或 pipeline。当槽处于迁移状态时, 批量操作会受到影响