为什么Redis集群的最大槽数是16384个?

大家好,我是大明哥,一个专注「死磕 Java」系列创作的硬核程序员。 本文已收录到我的小站:skjava.com


回答

在 Redis 集群中,Redis 根据公式 HASH_SLOT=CRC16(key) mod 16384 ,来确定客户端的 key 映射到哪个分片上,然后 Redis 会去相应节点进行操作。然而,CRC16 算法最多可产生 65535 个槽位,但是 Redis 的取模 是16384 ,主要基于如下两个原因:

  1. Redis 节点在发送心跳数据包时需要将所有槽都放入到这个心跳包里,如果采用 16384 个插槽,占用空间为 2KB(16384/8);如果采用 65536 个插槽,占空间 8KB (65536/8)。8KB 的心跳数据有点儿大。
  • Redis Cluster 不太可能扩展到超过 1000 个节点,太多会导致网络拥堵。选择 16384 ,照样可以确保每个主节点都有足够的槽。

所以,选择 16384 既可以保证集群中每个节点都有足够的槽,又能保证心跳数据包不会过大。

详解

Redis 的集群方案有三种:

  1. 主从复制模式
  2. Sentinel(哨兵)模式
  3. Redis Cluster 模式

在海量数据的存储下,Redis Cluster 模式是一种比较理想的模式。

Redis Cluster 采用分片模式,它定义了 16384 个 Slot 槽位,集群中每个节点负责 16384 个 Slot 槽中的部分槽以及这些槽所对应的所有数据。

客户端可以连接集群中的任意一个节点 A,客户端向节点 A 发送请求后,节点 A利用公式 slot = CRC16(key) % 16384 计算当前请求所在的 Slot,如果不是自己负责的 Slot,则将该 Slot 所在的 Redis 实例地址返回给客户端。客户端接收信息后会自动将请求发送给新的 Redis 实例。

CRC16 算法,生成 的hash 值有 16 位,可以产生 2^16 = 65536 个槽,既然可以产生这么多槽为什么 Redis-Cluster 的最大槽数为 16384 个呢?65536 不行吗?针对这个问题,Redis 官方其实已经给出了答案(github.com/redis/redis...):

大致意思有如下几个:

1、正常的心跳数据包携带节点的完整配置,它能以幂等方式来更新配置。如果采用 16384 个插槽,占空间 2KB ;如果采用 65536 个插槽,占空间 8KB 。

Redis 消息头结构如下(源码位置:redis-7.2.4/src/cluster.h):

注意红色框框部分,char 类型的 myslots[] ,长度为 CLUSTER_SLOTS/8,底层存储其实是一个 bitmap,每一个位代表一个槽,如果该位为1,表示这个槽是属于这个节点。那么他有多大呢?16384 / 8 / 1024 = 2kb,如果槽位数使用 65536,则占用空间大小为 65536 / 8 / 1024 = 8kb,作为心跳的数据包过于庞大。

2、Redis Cluster 不太可能扩展到超过 1000 个主节点。16384 个插槽范围比较合适,当集群扩展到1000个节点时,也能确保每个master节点有足够的插槽。

Redis 的集群主节点基本上不太可能超过 1000 个,集群节点越多,心跳包携带的数据就越多,如果超过 1000 个,可能会造成网络堵塞,所以 Redis 作者也不建议 Redis 集群节点数量超过 1000.

3、槽越少,节点越少,压缩比例就越高

Redis 节点配置信息中,节点所负责的槽是通过 bitmap 来保存的。

在传输过程中,Redis 会对 bitmap 进行压缩,bitmap 填充得越少,压缩效率就越高。所以槽越少,节点越少,压缩比例就越高。

4、总结

总结其实就两点原因:

  1. 16384 够用
  2. 65536 心跳消息头太大,得不偿失。
相关推荐
Victor3561 小时前
Hibernate(42)在Hibernate中如何实现分页?
后端
Victor3561 小时前
Hibernate(41)Hibernate的延迟加载和急加载的区别是什么?
后端
猪猪拆迁队1 小时前
2025年终总结-都在喊前端已死,这一年我的焦虑、挣扎与重组:AI 时代如何摆正自己的位置
前端·后端·ai编程
ConardLi1 小时前
SFT、RAG 调优效率翻倍!垂直领域大模型评估实战指南
前端·javascript·后端
Hooray2 小时前
2026年,站在职业生涯十字路口的我该何去何从?
前端·后端
唐叔在学习2 小时前
还在申请云服务器来传输数据嘛?试试P2P直连吧
后端·python
产幻少年2 小时前
redis位图
数据库·redis·缓存
开心猴爷3 小时前
iOS 代码混淆在项目中的方式, IPA 级保护实践记录
后端
魅影骑士00103 小时前
柯里化函数
后端·设计模式
短剑重铸之日3 小时前
《7天学会Redis》Day 4 - 高可用架构设计与实践
数据库·redis·缓存