redis cluster的16384个槽是逻辑分片抽象,非真实存储单元;每个key通过crc16(key) & 16383(等价于%16384)确定0–16383范围内的槽位,再由集群将槽段均匀分配给主节点,客户端据此直连路由并自动处理moved/ask重定向。

Redis Cluster 的 16384 个虚拟哈希槽(Slot)不是真实存在的存储单元,而是一种逻辑分片抽象机制——它把整个数据空间划分为固定数量的“桶”,每个 key 通过确定性哈希算出归属哪个桶,再由集群统一调度这些桶到具体主节点上。Java 客户端(如 Lettuce、Jedis)正是依赖这套 Slot 映射规则,实现无需代理的直连路由和自动重定向。
Slot 是怎么算出来的?
对任意 key,Redis 使用 CRC16 算法计算其校验值,再对 16384(即 214)取模,得到 0~16383 范围内的整数,这个结果就是该 key 所属的 slot:
-
公式:slot = CRC16(key) & 16383(等价于
CRC16(key) % 16384) - 比如 key="user:1001",执行
CLUSTER KEYSLOT user:1001可能返回6783,说明它落在第 6783 号槽 - 所有 key 都服从同一套计算逻辑,结果稳定可预测,不依赖当前集群状态
Slot 怎么分配给节点?
集群初始化或扩缩容时,运维人员(或自动化工具)把 16384 个 slot 拆分成若干连续段,手动或自动分配给各个 master 节点:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 例如 3 主节点集群,常见分配是:
nodeA → slot 0–5460,nodeB → slot 5461–10922,nodeC → slot 10923–16383 - 每个 master 节点只负责自己名下的 slot,从节点不持有 slot,只同步对应 master 的数据
- 集群元信息中维护一张全局 slot→node 映射表,所有节点都知晓这份映射
Java 客户端怎么用 Slot 路由请求?
以 Lettuce 为例,客户端启动时会向任一节点发送 CLUSTER SLOTS 命令,获取完整 slot 分配表并本地缓存:
- 发请求前,先对 key 计算 slot,查本地表知道该 slot 归属哪个节点
- 直接连接目标节点执行命令(如 SET/GET),不经过中间代理
- 若目标节点返回
MOVED 6783 192.168.1.10:7001,说明 slot 已迁走,客户端自动更新本地映射表并重试 - 若返回
ASK 6783 192.168.1.10:7001,表示迁移进行中,需先发 ASKING 再执行命令
为什么是 16384 而不是其他数字?
这不是随意选的,而是权衡通信开销与扩展性的工程决策:
- 心跳包里要携带每个节点负责的 slot 位图(
myslots[CLUSTER_SLOTS/8]),16384 个 slot 对应位图仅 2KB;若用 65536 个 slot,位图达 8KB,每秒多次心跳会显著增加带宽压力 - 16384 足够支持上千节点规模(每个节点平均分到十几甚至上百个 slot),又不至于让 slot 映射表过大影响传播效率
- CRC16 输出 0–65535,取模 16384 是为了在哈希空间内做均匀截断,同时避开高位冗余
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










