连载中 15/20

Cluster:数据分片与横向扩展

2026-06-01 · 4809 阅读 · 0 评论 · 0 赞

哨兵的盲区:内存天花板

主从加哨兵,可用性齐了,但所有从库都是主库的完整镜像——数据总量被钉死在单机内存上限上。业务数据涨到几十上百 GB,单机装不下、fork 越来越慢、大实例的持久化与迁移处处是坑(持久化篇的预告在这里兑现)。出路只有分片:把数据切开,每个节点只装一小块。Redis Cluster 就是官方的分片方案,分片加副本二合一,不再需要哨兵。

16384 个槽:数据的门牌号

Cluster 的分片规则不在节点数上做除法,而是引入一个中间层:16384 个哈希槽(slot)。每个 key 按公式定位:

slot = CRC16(key) mod 16384

item:detail:10086   --> slot 8281  --> 节点A
user:session:9527   --> slot 12182 --> 节点B

每个节点负责一段槽区间,key 按槽就位。为什么是「槽」而不是直接按节点哈希?因为槽是数据与节点之间的解耦层:扩容缩容时移动的是槽,key 跟着槽走,映射关系的调整粒度可控——这是预分片思想,和第 9 篇的多副本打散一脉相承。有个细节:想要多个 key 落进同一个槽(同槽才能做多 key 操作),用 hash tag——key 里花括号圈住的部分参与哈希:order:{1001}:info 与 order:{1001}:items 永远同槽。

重定向与 smart client

key 发到了不归它管的节点怎么办?节点不代劳,回一个 MOVED 错误,附上正确的节点地址——「这 key 不归我,去问 A」。每次都重定向浪费一个来回,所以 Cluster 的客户端都是 smart client:本地维护「槽到节点」的映射表,绝大多数请求直接命中正确节点,MOVED 收到一次就刷新一次映射。槽迁移过程中的过渡态则用 ASK 错误处理:本次去新节点试试,但映射表不变——它是「一次性指路」,MOVED 是「搬家通知」。

节点之间互相发现、交换状态,靠的是 gossip 协议:每个节点随机找几个节点互发消息,集群状态像八卦一样传遍全网——没有中心节点,故障判定最终由多数派拍板,与哨兵的仲裁思路一脉相承。

代价清单:多 key 操作的枷锁

分片不是免费午餐,代价列在明面上:跨槽的多 key 命令直接报错——MGET 打散在三个节点上的 key、跨槽的 Lua、跨槽事务都不可用,只能用 hash tag 凑槽或客户端自己拆分聚合;扩容迁移最怕大 Key——槽迁移以 key 为粒度,一个几百 MB 的大 key 迁移时阻塞两边节点(大 Key 篇又添一条罪状);运维复杂度上升——节点规划、槽分配、故障演练都要跟上。所以选型收束成一句话:数据量单机装不下、或写 QPS 单机扛不住,上 Cluster;只是要高可用,主从加哨兵更简单。能用简单架构解决的,别急着上复杂架构。

到这里,Redis 自身的机制——内存、过期、复制、持久化、哨兵、分片——全部盘完。视野重新拉回应用层:本地缓存与分布式缓存怎么搭成多级体系?命中率这个核心指标怎么算、怎么养?下半场从第 16 篇开始。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#RedisCluster#哈希槽#MOVED#ASK#gossip#数据分片

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞