Redis 切片集群扩容:从 100 到 1000 节点的无感迁移

讲述链条

Gossip 协议维护槽位路由表 → CRC16 计算槽位(16384个) → MOVED/ASK 重定向机制 → 槽位迁移流程 → 与一致性 Hash 对比

核心表述

Redis Cluster 从 100 扩展到 1000 节点可以实现无感迁移,核心在于它采用了固定槽位 + 映射表的设计。集群中固定有 16384 个 Hash Slot,通过 CRC16(key) % 16384 计算槽位,然后查询槽位路由表找到对应节点。节点数和槽位数解耦,扩容时只需重新分配槽位映射关系即可。

节点间通过 Gossip 协议维护槽位路由表,每个节点都记录所有槽位的分配情况。客户端可以连接集群中任意节点,如果访问的 key 不在当前节点,会返回 MOVED 重定向(包含槽位和目标地址),客户端更新本地缓存并重新发送请求。

槽位迁移时,源节点标记为 MIGRATING,目标节点标记为 IMPORTING,迁移期间如果 key 未迁移则正常处理,如果 key 已迁移则返回 ASK 临时重定向(客户端先发送 ASKING 命令再执行操作,不更新缓存)。全部迁移完成后才返回 MOVED,客户端更新缓存。

为什么是 16384 个槽位? 心跳包携带槽位信息的位图,16384 个槽位只需 2KB(16384/8),而 65536 个需要 8KB,网络开销增加 4 倍。Redis Cluster 设计目标支持 1000 个节点左右,16384 个槽位足够分配且迁移粒度适中。

为什么用 Hash Slot 不用一致性 Hash? 一致性哈希扩容时需要逐个 key 重新计算 hash(key) 判断是否迁移,实现复杂。Hash Slot 直接将一个槽位的所有数据整体迁移,实现更简单。另外槽位映射表更灵活,可以方便地调整槽位分配策略,而一致性哈希的迁移范围不可控。

为什么用 CRC16? CRC16 是硬件友好算法,速度快且输出范围 0-65535 对 16384 取模后分布均匀。相比 MD5/SHA1 太慢,不需要加密强度,只需分布均匀即可。实现简单,易于维护。