1. 引言很多刚接触 Redis Cluster 的同学都会有一个疑问为什么集群要设计成 16384 个槽slot而不是 1000 个、10000 个或者更多这篇文章就来彻底讲清楚 16384 个槽到底是什么、怎么用以及为什么偏偏是这个数字。2. 槽Slot是什么Redis Cluster 并没有使用一致性哈希而是采用了一种叫做「哈希槽」hash slot的机制。简单来说整个集群被逻辑上划分为16384 个槽编号从0到16383。每个键key都会通过下面的公式被映射到其中一个槽上HASH_SLOT CRC16(key) % 16384也就是说先对 key 做 CRC16 校验得到一个 16 位的整数再对 16384 取模最终得到该 key 所属的槽编号。3. 槽与节点的关系槽是数据分布的最小逻辑单元而节点master是真正存储数据的物理单元。每个 master 节点负责一部分槽一个槽只能属于一个 master所有槽都被分配完毕后集群才处于正常状态cluster_state:ok。例如一个 3 主节点的集群可以这样分配节点负责的槽范围Master A0 – 5460Master B5461 – 10922Master C10923 – 16383当客户端要读写某个 key 时先算出它的槽编号再通过集群的「槽 → 节点」映射表直接定位到对应的 master 节点从而完成请求。4. 为什么是 1638416384 这个数字并不是随便定的它背后有性能和内存两方面的考量。4.1 心跳包要尽量小集群中的每个节点都会通过 Gossip 协议定期广播自己的状态。心跳包中需要携带「本节点负责哪些槽」的位图信息。如果用 16384 个槽每个槽只占 1 个 bit那么完整的槽位图大小就是16384 / 8 2048 字节 2 KB这个体积非常小可以轻松放进心跳包里网络开销很低。4.2 槽数量不能太少如果槽数量太少比如只有 100 个那么当集群扩容、缩容或做数据迁移时每个槽里包含的 key 会非常多导致迁移粒度太粗、数据倾斜明显很难做到均衡。4.3 槽数量不能太多如果槽数量太多比如 65536 个虽然迁移粒度更细但会带来两个问题槽位图会变成65536 / 8 8 KB心跳包明显变大网络开销增加节点间同步槽信息、维护映射表的成本也会上升。所以 16384 是一个在「迁移粒度」和「通信开销」之间取得平衡的经验值。5. 槽的迁移当集群需要扩容、缩水或重新平衡时实际上做的事情就是「槽迁移」。迁移过程是增量的把某个槽从源节点迁移到目标节点时槽内的 key 会一批一批地搬过去期间集群仍然可以对外提供服务。CLUSTER SETSLOT slot MIGRATING target_node_id CLUSTER SETSLOT slot IMPORTING source_node_id迁移完成后槽的归属关系更新客户端也会通过MOVED或ASK重定向拿到最新的槽映射。6. 总结Redis Cluster 的 16384 个槽本质上是一张把「键空间」均匀切分出来的逻辑地图每个 key 通过CRC16(key) % 16384定位到唯一槽每个 master 负责一部分槽槽的迁移就是集群扩容、缩容和再平衡的核心手段16384 这个数字是官方在迁移粒度、心跳包大小和内存开销之间权衡后的最佳选择。理解了槽你就理解了 Redis Cluster 的数据分布与扩缩容原理。