问答题377/1053Redis在集群种查找key的时候,是怎么定位到具体节点的?

难度:
2021-11-02 创建

参考答案:

在 Redis 集群中,查找一个给定的 key 是通过 一致性哈希哈希槽 机制来定位到具体的节点的。Redis 集群总共有 16384 个哈希槽,每个哈希槽由一个或多个节点(主节点和从节点)负责。当客户端请求一个 key 时,Redis 集群通过以下步骤来定位该 key 的存储位置:

1. 哈希槽(Hash Slot)

Redis 集群使用 哈希槽 来分配数据。在 Redis 集群中,所有的数据被映射到 16384 个槽(slots)上。每个节点(主节点或从节点)负责一部分槽,并存储对应槽中的数据。

2. key 定位到哈希槽

当客户端查询某个 key 时,Redis 集群使用一个 哈希函数 来计算该 key 的哈希值,并根据这个哈希值来决定该 key 属于哪一个槽。

  • 哈希计算:Redis 集群使用 CRC16 哈希算法来计算 key 的哈希值。具体步骤如下:

    • 首先,对 key 应用 CRC16 哈希算法,得到一个 16 位的哈希值。
    • 然后,将这个哈希值对 16384 取模,得到一个 0 到 16383 之间的数字,表示该 key 所属于的槽(slot)。
    slot = CRC16(key) % 16384
    

    例如,假设 key 的哈希值为 123456,则对应的槽为 123456 % 16384 = 8528,表示 key 应该存储在槽 8528 中。

3. 槽与节点的映射

在 Redis 集群中,哈希槽是与 节点 绑定的。每个节点(主节点)负责一定数量的槽。当一个节点启动时,它会向集群注册自己负责的槽区间。例如,节点 A 可能负责槽 0-5000,节点 B 负责槽 5001-10000,以此类推。

客户端可以通过 集群总是返回槽的位置信息 来确定该查询的槽在哪个节点上。

4. 节点定位

一旦确定了某个 key 所在的槽,Redis 集群就能够根据槽到节点的映射,定位到正确的节点来处理这个请求。

Redis 集群通过一个 槽到节点的映射表 来维持哪些节点负责哪些槽。每个节点都会存储整个集群的槽映射表(slot mapping),并在集群发生变化时,向其他节点同步这些信息。

  • 客户端路由:客户端请求一个 key 时,客户端根据槽映射表找到对应的节点,并将请求发送到该节点。如果该节点不可用,客户端会收到一个 MOVED 错误,提示该槽的数据已经迁移到其他节点,然后客户端会自动路由到新的节点。

5. 从节点和故障转移

如果主节点不可用,Redis 集群会进行故障转移,将某个从节点提升为主节点。此时,槽的分配和路由逻辑会自动更新,客户端在访问时仍然能够通过路由表正确找到新的主节点。

6. 单节点查询与跨节点查询

  • 单节点查询:如果查询的 key 在同一个节点的槽中,客户端直接访问该节点即可。
  • 跨节点查询:如果查询的 key 不在当前节点的槽中,客户端会收到一个 MOVED 错误,提示该槽的数据已经迁移到其他节点。客户端根据 MOVED 错误的信息,自动重定向到正确的节点。

7. 一致性哈希与槽迁移

当 Redis 集群发生变化时(如新增节点、节点失败或节点恢复),会有一些槽从一个节点迁移到另一个节点。这个过程会通过 数据迁移 来完成,确保每个槽的数据都能够正确地分配给新的节点。

  • 在数据迁移过程中,客户端会根据槽映射表(通过 MOVED 错误)自动重定向请求到新节点。

8. 客户端与 Redis 集群的通信

Redis 集群通常依赖于客户端支持集群模式来进行自动路由。在集群模式下,客户端库(如 Jedis、Lettuce、Redis-py 等)会自动处理 key 到槽的映射以及节点的路由,不需要手动干预。

最近更新时间:2024-12-09

预览

小程序刷题更方便

预览

关注公众号获取最新面经

预览

咨询辅导服务/加面试交流群