P52 Redis Cluster 为什么是 16384
面试题:Redis Cluster 的槽位为什么是 16384 个,而不是更多(如 65536)?
1. 背景
Redis Cluster 采用**虚拟槽(slot)**分片:
text
key → CRC16(key) % 16384 → 落到某个槽
16384 个槽平均分配给集群中的节点(如 3 节点各约 5461 个槽)2. 为什么是 16384(视频/官方解释)
① 心跳消息要携带槽位信息,太多会撑爆带宽
集群节点间通过心跳消息交换信息,每条消息要带上:
- 本节点持有的槽位 bitmap;
- 16384 个槽的 bitmap = 2KB(16384 bit / 8);
- 若用 65536 个槽,bitmap = 8KB,心跳消息体积变大 4 倍,网络开销明显增加。
② 节点数一般不会太大(官方建议 ≤ 1000 节点)
- 16384 个槽对 ≤1000 节点的集群绰绰有余;
- 槽太少则每个节点分到的槽太大(迁移粒度粗),16384 已经是"够用且不浪费"的平衡。
③ 其他原因(社区讨论)
- CRC16 的散列质量:CRC16 本身只有 16 位,取模 16384(2^14)比取模 65536(2^16)的分布更不容易出现偏差;
- 压缩 bitmap 的效率和心跳消息大小权衡;
- Redis 作者 antirez 曾解释:槽位数量基于"消息体大小 + 集群规模"的折中,65536 会让心跳和 Gossip 协议负担过重。
3. 高频追问
- "槽位可以调整吗":16384 是写死的常量(
CLUSTER_SLOTS),不能改; - "为什么用 CRC16":散列均匀、实现简单、对 key 分布友好;
- "槽和一致性哈希的区别":一致性哈希是哈希环(虚拟节点),Cluster 用固定槽位,迁移和增删节点更可控。
4. 加分点
- 精确说出 16384 bit = 2KB,65536 bit = 8KB(心跳消息大小的关键论据);
- 说明槽迁移(reshard)是按 slot 粒度的,16384 个槽让迁移粒度更细、更均衡;
- 提到 Gossip 协议:节点间互相交换槽信息,消息体越小传播越快。
一句话总结
16384 是心跳消息体大小(2KB bitmap)与集群规模(≤1000 节点)的折中:槽太多会放大 Gossip 带宽,槽太少迁移粒度粗;CRC16 取模 16384 也保证分布均匀,所以是写死的常量。