第17章 集群

用16384槽、节点握手、MOVED与ASK、重新分片、复制和Gossip消息解释Redis Cluster 覆盖8个正式节点,并以Redis 3.0源码、故障和恢复对账验收。

学习目标

  • 能解释 16384 槽的映射与分配
  • 能说明 gossip 协议的拓扑收敛
  • 能分析重新分片与 ASK 转向的流程

为什么从“16384槽迁移路由台”开始

第17章 集群的核心任务是用16384槽、节点握手、MOVED与ASK、重新分片、复制和Gossip消息解释Redis Cluster。命令返回值只暴露外层合同;实现解释还必须连接内存结构、写入与读取路径、事件顺序以及失败后的旧状态回收。16384槽迁移路由台把这些关系放进同一条可复位轨迹。

先写预测:当槽状态由“migrating/importing”进入“已转移”时,哪个可观察状态最先变化?再规定什么结果会推翻当前解释。交互中的分数只表达透明因果方向,不冒充真实Redis测量。

来源、版次与独立重写边界

黄健宏作者读者服务页确认正式出版新版以Redis 3.0为源码基线,列出4部分、24章及完整小节,并链接Redis 3.0中文注释源码。本课程据此映射24个正式单元、145个目录节点,另设学习地图和总复习;未取得出版正文授权,目录只界定范围,不宣称复现原书正文。

本章字段与控制流由Redis官方3.0源码:cluster.c和作者注释源码交叉核对;Redis当前持久化文档只用于辨认版本差异。中文解释、图示、交互、实验与答案均为独立教学重写,不把目录页或代码仓库许可证误报为原书许可证。

本章术语与源码合同

第17章 集群必须守住“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”。观察同时记录16384槽迁移路由台一致率与请求位置分叉风险;只有结构快照、函数入口、运行结果和故障反例互相一致,才接受实现结论。

⚡ Redis 集群槽分配与迁移
Redis 集群槽分配(128 个槽,3 个节点)每格代表一个槽,颜色表示所属节点;新增节点后用迁移按钮重新分配N1N2N3槽数: N1=43 N2=43 N3=42
16384 个槽是 Redis 集群的固定值。槽是键到节点的映射单位,也是重新分片的最小迁移单元。每个槽在迁移期间会返回 ASK 转向,客户端收到后重定向到目标节点。
操作日志
  1. 1.初始化:128 个槽均匀分布在 3 个节点上。

作者目录逐项深读

节点

四级证据 1/8。 clusterNode记录名字、纪元、地址、标志、槽位与连接;握手消息把新节点加入已知拓扑。本节点用“节点”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证节点时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

槽指派

四级证据 2/8。 集群固定16384槽,节点位图与全局slots映射必须一致;槽归属通过配置纪元解决新旧声明。本节点用“槽指派”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证槽指派时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

在集群中执行命令

四级证据 3/8。 节点先计算所有键的槽并检查归属;稳定槽返回MOVED,迁移中的局部键可能引导ASK。本节点用“在集群中执行命令”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证在集群中执行命令时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

重新分片

四级证据 4/8。 迁槽依次设置importing/migrating状态并搬迁键,完成后广播新所有者,过程不能丢失路由边界。本节点用“重新分片”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证重新分片时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

ASK错误

四级证据 5/8。 ASK只授权客户端对下一条命令先发ASKING访问目标节点,不应像MOVED那样永久更新槽缓存。本节点用“ASK错误”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证ASK错误时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

复制与故障转移

四级证据 6/8。 领头者选择合格副本晋升,重配其余副本并最终让旧主恢复后成为新主副本。本节点用“复制与故障转移”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证复制与故障转移时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

消息

四级证据 7/8。 cluster bus的PING、PONG、MEET与FAIL等消息传播节点状态、槽位和故障意见,Gossip是最终收敛信号而非瞬时真相。本节点用“节点”作观察点,执行rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证消息时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

重点回顾

四级证据 8/8。 第17章 集群的回顾要重新证明“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,并用同一输入比较结构前态、变更轨迹、故障首错与恢复后态

验证重点回顾时,先预测槽状态从“migrating/importing”切到“已转移”会改变哪个字段、偏移、文件或消息;再固定请求位置做一次对照。若故障注入没有破坏“每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主”,就撤回当前解释而不是补写故事。

最小源码与运行切片

+git clone --branch 3.0 --depth 1 https://github.com/redis/redis.git redis-3.0
+cd redis-3.0
+rg 'getNodeByQuery|clusterRedirectClient|clusterCron' src/cluster.c

该切片固定Redis 3.0分支、编译器、配置、数据集和命令序列;先保存结构或函数位置,再运行隔离实例。任何持久化损坏、断线、故障转移、大键或高流量实验都必须使用临时数据并规定CPU、内存、磁盘、延迟和停止上限。

unit: rdi-17-cluster
source_file: cluster.c
axis_a: "槽状态"
axis_b: "请求位置"
fault: "迁槽时混淆ASK与MOVED,或让同一槽同时拥有两个可写主"
invariant: "每个槽恰有有效所有者,迁移状态可路由请求,故障转移不产生两个合法写主"
replay: same_version_same_input

三个必须主动触发的误区

误区 1

现象 → 跨槽事务直接用 原因 → CROSSSLOT 报错 修法 → hash tag 归组相关键

误区 2

现象 → 扩容后忘记分片 原因 → 新节点空载浪费 修法 → 扩容即重分片均衡槽位

误区 3

现象 → 忽视 gossip 开销 原因 → 大集群通信膨胀 修法 → 控制集群规模与分区

小结

  • 16384 个槽位划分数据空间
  • 节点间 gossip 交换拓扑
  • 重新分片在线迁移槽
  • ASK 与 MOVED 引导客户端
  • 集群故障转移自动化

练习、答案与节点验证

练习

问题 1: 为什么集群选择 16384 个槽而不是按节点动态分?

问题 2: 重新分片期间客户端访问被迁移的键会怎样?

问题 3: 用 hash tag 设计一个用户相关键的分布方案。(独立实现)

术语复核与本章回顾

完成第17章 集群意味着能从cluster.c解释用16384槽、节点握手、MOVED与ASK、重新分片、复制和Gossip消息解释Redis Cluster,能运行章专属状态实验,能制造反例并在复位后证明旧状态没有残留。

资料与写作方式声明

本章以黄健宏《Redis设计与实现》(机械工业出版社)权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…