集群哈希槽机制

集群哈希槽机制

什么是哈希槽

Redis Cluster 使用哈希槽(Hash Slot) 来管理数据分布。整个集群共有 16384 个哈希槽,编号从 0 到 16383。每个 Key 通过 CRC16 算法计算出哈希值后,对 16384 取模,决定它属于哪个槽:

slot = CRC16(key) % 16384

为什么是 16384 个槽

这个数字不是随意选的,而是经过精心设计的。作者 antirez 在设计中考虑了以下因素:

1. 心跳包大小控制

集群节点之间通过 Gossip 协议定期交换信息。每个心跳包中包含了节点的槽位信息(一个 bit 代表一个槽)。16384 个槽对应 2048 字节(16384 / 8 = 2048)的位图。

如果槽位数量太大(例如 65535 个),位图就会变成 8KB,导致心跳包变大,占用更多网络带宽。

2. 集群规模适配

16384 个槽对于最大 1000 个节点的集群已经足够。即使只有少数节点,每个节点也能分配到足够多的槽来实现良好的负载均衡。

3. CRC16 算法的输出范围

CRC16 算法输出 16 位(65536 个可能值),16384 正好是 65536 的 1/4,取模后的分布均匀性已经足够好。

哈希槽如何分配

每个主节点负责一部分哈希槽。例如一个 3 节点的集群:

节点 A:槽 0-5460
节点 B:槽 5461-10922
节点 C:槽 10923-16383

当需要扩展节点时,Redis 会从现有节点中移动一部分槽到新节点。槽迁移过程中,数据也会同步迁移。

Key 到节点的定位流程

正常情况

SET user:1001 "Alice"
    CRC16("user:1001") % 16384  计算出槽位 7256
    ↓
客户端本地缓存槽-节点映射表   7256 在节点 B
    ↓
直接连接节点 B 执行命令

槽位变更(迁移/故障转移)

如果客户端请求的槽不在当前节点上,节点会返回 MOVED 重定向

GET user:1001
    ↓
客户端连接到节点 A(但槽 7256 实际上在节点 B)
    ↓
节点 A 返回: -MOVED 7256 192.168.1.2:6379
    ↓
客户端更新本地缓存,重新连接到节点 B

Hash Tag:让多键操作跨槽

由于多键操作(MSET、MGET、事务、Lua 脚本)要求所有 Key 在同一个槽,Redis Cluster 提供了 Hash Tag 机制。如果 Key 中包含 {},则只对 {} 内的内容计算哈希:

user:{1001}   CRC16("1001") % 16384
order:{1001}  CRC16("1001") % 16384   与上面相同!

这样,user:1001order:1001 就会被分配到同一个槽,支持跨 Key 操作。

槽迁移过程

当增加或删除节点时,需要重新分配槽:

  1. 在目标节点上执行 CLUSTER SETSLOT IMPORTING
  2. 在源节点上执行 CLUSTER SETSLOT MIGRATING
  3. 源节点迭代槽中的所有 Key,逐个迁移到目标节点
  4. 迁移完成后广播槽归属变更

迁移过程中的 Key,如果被客户端访问,节点会返回 ASK 重定向(临时重定向,与 MOVED 不同),客户端需要先发 ASKING 命令再操作。

总结

哈希槽机制是 Redis Cluster 数据分布的核心。16384 个槽在集群规模扩展心跳包大小之间取得了良好平衡。通过 CRC16 算法和槽映射,Redis 实现了数据的自动分片,同时通过 Hash Tag 提供了有限的多键操作能力。理解哈希槽机制对于掌握 Redis Cluster 的工作原理至关重要。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容