ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Redis Cluster 为什么选择 ‌16384 个虚拟槽(Hash Slot)

Redis Cluster 为什么选择 ‌16384 个虚拟槽(Hash Slot) 文章目录为了让你更直观地理解 Redis Cluster 为什么选择 16384 个虚拟槽Hash Slot而不是直接对节点数取模或使用一致性哈希我们可以通过一个“图书馆分书”的类比来拆解这个设计。一、 核心概念类比书架 vs. 箱子想象你要管理一个巨大的图书馆Redis 集群里面有成千上万本书Key-Value 数据。如果采用“简单求余算法”直接绑定节点做法你有 3 个书架节点 A、B、C。每来一本书你计算书名哈希值 % 3。结果是 0 放 A1 放 B2 放 C。问题现在业务扩张你要加第 4 个书架节点 D。公式变成了 书名哈希值 % 4**。后果原来在 A 的书可能因为余数变了现在应该去 C 或 D。几乎所有书的位置都乱了你需要把全图书馆的书重新搬运一遍。期间图书馆必须闭馆服务不可用或者读者会找不到书缓存击穿。如果采用“虚拟槽方案”引入中间层做法不管有多少书架你先准备 16384 个标准纸箱Slot 0 ~ 16383。每来一本书计算CRC16(书名) % 16384得到一个数字比如 8000把书放进 8000 号纸箱。关键步骤你把这 16384 个纸箱分配给书架。书架 A 负责拿纸箱 0~5460书架 B 负责拿纸箱 5461~10922书架 C 负责拿纸箱 10923~16383注意书是固定在纸箱里的纸箱才是移动的单位。二、 举例说明扩容时的“神操作”现在你要增加第 4 个书架节点 D。场景从 3 节点扩容到 4 节点数据分布天然均衡为什么是 1638416384 这个数字不大不小。如果太少比如 10 个槽3 个节点分 10 个槽分别是 3、3、4很不均匀。如果太多比如 100 万槽节点之间同步“哪个节点负责哪些槽”的状态信息Gossip 协议时数据包太大网络开销巨大。16384 刚好能让大部分集群几十到几百节点分得比较均匀且状态包很小每个节点只需几 KB 内存记录映射关系。迁移粒度精确到整槽怎么搬目标让 A、B、C、D 四个书架负担差不多。原本每个书架约负责 5461 个槽现在每个应该负责约 4096 个槽。操作我们不需要动所有的书。我们只需要从 A、B、C 那里每人“借”走大约 1365 个纸箱Slot交给 D。比如从 A 拿走 Slot 100~1464从 B 拿走 Slot 5500~5964… 等等。效率极高Redis 迁移数据时不是一个个 Key 慢慢传而是批量迁移整个 Slot 里的所有 Key。命令MIGRATE可以一次性把一个 Slot 下的几百上千个 Key 打包发给新节点。这比逐个 Key 迁移快得多且减少了网络往返次数RTT。极大地降低元数据维护成本怎么找书元数据是什么 就是“哪个书架负责哪些纸箱”的地图。低成本体现在 Redis Cluster 中每个节点都会保存一份完整的“槽-节点映射表”。因为槽只有 16384 个这个映射表非常小。当节点间通过 Gossip 协议互相打招呼交换状态时携带这份地图的开销极低。如果是一致性哈希节点变动会影响环上很大一片区域状态同步复杂而虚拟槽方案中只有被迁移的那几个 Slot 的状态变了其他 16000 多个 Slot 的归属权没变集群大部分成员无需更新认知广播压力极小。三、 客户端访问流程MOVED 重定向假设你要找一本书user:1001客户端计算CRC16(user:1001) % 16384 8000。查找地图客户端本地缓存着地图知道 Slot 8000 目前在 节点 B。发送请求客户端直接连节点 B问“我要 user:1001”。正常情况节点 B 说“在这。”返回数据。扩容中途情况假设 Slot 8000 正在从 B 迁移到 D。客户端连 BB 发现这书已经搬走了或者正在搬。B 返回错误MOVED 8000 D的IP:端口。客户端收到后更新本地地图“哦原来 Slot 8000 现在归 D 管了。”客户端重试连 D拿到数据。四、 总结为什么这样设计最好特性简单求余 (Modulo)一致性哈希 (Consistent Hashing)虚拟槽 (Hash Slot)扩容影响全量数据迁移 (灾难级)部分数据迁移但边界模糊仅迁移部分 Slot (精准可控)迁移单位单个 Key单个 Key / 虚拟节点整个 Slot (批量 Key)元数据大小极小 (仅节点数)较大 (需维护虚拟节点环)适中且固定 (16384 个整数映射)实现复杂度低高 (需处理虚拟节点倾斜)中 (逻辑清晰易于工程化)均衡性节点数少时不均依赖虚拟节点数量调优天然均匀 (16384 可被多数节点数整除或近似均分)一句话总结虚拟槽方案就像是在“数据”和“物理节点”之间加了一层“可移动的集装箱Slot”。扩容时我们只搬运集装箱而不需要重新打包里面的货物。16384 这个数量既保证了集装箱足够多以便均匀分配又保证了集装箱编号列表足够短以便快速同步。
返回列表