在 Redis 集群中,如何根据键定位到对应的节点?

Sherwin.Wei Lv7

在 Redis 集群中,如何根据键定位到对应的节点?

回答重点

Redis 集群将数据分布到 16384 个哈希槽(slots) 中,每个键通过哈希函数计算出一个槽位编号,然后根据槽位编号定位到具体的节点,具体是使用 CRC16 哈希函数计算键的哈希值,然后对 16384 取模,得到哈希槽编号(范围是 0 到 16383)。

扩展知识

Redis 集群节点的通信

Redis 集群节点在一开始的时候,只知道自己的槽位,不知道其他节点槽位的,然后它们之间会通过 Gossip 协议使用 ping 命令和 pong 响应进行通信,彼此之间交换槽位的信息。

这样之后,Redis 集群的节点之间就互相知道彼此的槽位。

访问 Redis 集群时,如何得知 key 所对应的节点

Redis 客户端通过 Key 访问数据的时候,可以将请求打在 Redis 集群中的任意一个节点,在得知这个前提之后,我们来对以下这个流程进行分析:

1)Redis 客户端会使用 CRC16 算法计算出 Key 的哈希值,然后将哈希值对 16384 取模,从而计算 key 最终要落到的槽位。

2)一般客户端在启动时会从集群中获取哈希槽到节点的映射关系,因此可以选择对应的节点。

3)如果节点上有数据则直接返回,如果访问的 key 不在连接的节点上时,Redis 会返回一个重定向命令 MOVEDASK

  • 当客户端收到 MOVED 响应时,表示 key 所在的哈希槽已经被移动到另一个节点,客户端需要更新哈希槽映射并重试操作。
  • 当客户端收到 ASK 响应时,表明 Redis 集群进行伸缩(扩容 / 缩容)。

4)Redis 客户端根据 MOVED/ASK 指令重定向到正确的 Redis 节点。

下图演示 MOVED 情况:

Snipaste_2024-06-12_05-20-06.jpg

Redis 集群更详细的介绍,可以查看面试鸭《652. Redis 集群的实现原理是什么?

ASK 重定向的工作原理

1)客户端请求:

客户端发送一个命令来访问某个 key。

2)哈希槽迁移中的源节点:

如果该 key 所在的哈希槽正在从源节点迁移到目标节点,源节点会返回一个 ASK 重定向指令。

3)客户端处理 ASK 重定向:

客户端收到 ASK 重定向后,首先发送一个 ASKING 命令到目标节点,随后重新发送原始命令到目标节点。

为什么客户端需要先发送一个 ASKING 命令到目标节点,然后再发送实际的请求?

因为集群扩容还未完成,所以理论新的节点还未完全拥有这个槽,而 ASKING 命令其实是一个临时授权,告诉目标节点即使该节点还没有正式拥有该哈希槽,也要暂时处理这个请求。

如果没有先发送 ASKING 命令,目标节点可能会因为还没有正式接管哈希槽而拒绝处理请求。

哈希标签(Hash Tag)机制

为了让多个键可以存储在同一个槽位中,Redis 提供了哈希标签功能。

如果键包含大括号 {},则只对括号内的部分进行哈希计算。例如键 "user:{1001}:name""user:{1001}:age" 会被映射到同一个哈希槽,因为 {1001} 的内容相同。

通过这种方式,可以确保具有相同标签的键都落在同一个节点上,从而简化分布式场景下的操作,例如执行多键事务或管道操作。

Comments