第16章 Sentinel
沿Sentinel初始化、INFO发现、hello频道、主客观下线、领头选举与故障转移还原高可用 覆盖11个正式节点,并以Redis 3.0源码、故障和恢复对账验收。
学习目标
- 能区分主观与客观下线判定
- 能描述哨兵选举与故障转移流程
- 能说明客户端如何感知新主库
为什么从“Sentinel投票与故障转移台”开始
第16章 Sentinel的核心任务是沿Sentinel初始化、INFO发现、hello频道、主客观下线、领头选举与故障转移还原高可用。命令返回值只暴露外层合同;实现解释还必须连接内存结构、写入与读取路径、事件顺序以及失败后的旧状态回收。Sentinel投票与故障转移台把这些关系放进同一条可复位轨迹。
先写预测:当故障认定由“主观下线”进入“客观下线”时,哪个可观察状态最先变化?再规定什么结果会推翻当前解释。交互中的分数只表达透明因果方向,不冒充真实Redis测量。
来源、版次与独立重写边界
黄健宏作者读者服务页确认正式出版新版以Redis 3.0为源码基线,列出4部分、24章及完整小节,并链接Redis 3.0中文注释源码。本课程据此映射24个正式单元、145个目录节点,另设学习地图和总复习;未取得出版正文授权,目录只界定范围,不宣称复现原书正文。
本章字段与控制流由Redis官方3.0源码:sentinel.c和作者注释源码交叉核对;Redis当前持久化文档只用于辨认版本差异。中文解释、图示、交互、实验与答案均为独立教学重写,不把目录页或代码仓库许可证误报为原书许可证。
本章术语与源码合同
第16章 Sentinel必须守住“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”。观察同时记录Sentinel投票与故障转移台一致率与选举状态分叉风险;只有结构快照、函数入口、运行结果和故障反例互相一致,才接受实现结论。
作者目录逐项深读
启动并初始化Sentinel
四级证据 1/11。 Sentinel以特殊服务器模式启动,载入监控主节点配置并建立命令连接、订阅连接和周期任务。本节点用“启动并初始化Sentinel”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证启动并初始化Sentinel时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
获取主服务器信息
四级证据 2/11。 Sentinel周期向主节点发送INFO,刷新运行ID、角色、从节点地址与复制状态。本节点用“获取主服务器信息”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证获取主服务器信息时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
获取从服务器信息
四级证据 3/11。 从主节点INFO发现副本后为其创建实例,并继续用INFO核对角色、主节点地址和偏移。本节点用“获取从服务器信息”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证获取从服务器信息时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
向主服务器和从服务器发送信息
四级证据 4/11。 命令连接承担PING、INFO和故障转移配置;每条命令结果与最后可用时间共同更新状态。本节点用“向主服务器和从服务器发送信息”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证向主服务器和从服务器发送信息时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
接收来自主服务器和从服务器的频道信息
四级证据 5/11。 Sentinel通过__sentinel__:hello交换自身纪元、监控主节点和候选领头信息,以发现其他Sentinel。本节点用“接收来自主服务器和从服务器的频道信息”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证接收来自主服务器和从服务器的频道信息时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
检测主观下线状态
四级证据 6/11。 单个Sentinel在down-after时间内收不到有效回复就标记S_DOWN,这只是本地判断。本节点用“检测主观下线状态”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证检测主观下线状态时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
检查客观下线状态
四级证据 7/11。 对主节点还要询问其他Sentinel;达到quorum才标记O_DOWN并进入故障转移候选流程。本节点用“启动并初始化Sentinel”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证检查客观下线状态时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
选举领头Sentinel
四级证据 8/11。 每个纪元一个Sentinel只投一票,候选者既要满足多数票也要达到配置法定人数。本节点用“获取主服务器信息”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证选举领头Sentinel时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
故障转移
四级证据 9/11。 领头者选择合格副本晋升,重配其余副本并最终让旧主恢复后成为新主副本。本节点用“获取从服务器信息”作观察点,执行rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。
验证故障转移时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
重点回顾
四级证据 10/11。 第16章 Sentinel的回顾要重新证明“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,并用同一输入比较结构前态、变更轨迹、故障首错与恢复后态
验证重点回顾时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
参考资料
四级证据 11/11。 本章目录范围由作者页面确认,字段和控制流回到Redis 3.0的sentinel.c与黄健宏注释源码核验;新版资料只承担差异说明
验证参考资料时,先预测故障认定从“主观下线”切到“客观下线”会改变哪个字段、偏移、文件或消息;再固定选举状态做一次对照。若故障注入没有破坏“故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致”,就撤回当前解释而不是补写故事。
最小源码与运行切片
+git clone --branch 3.0 --depth 1 https://github.com/redis/redis.git redis-3.0
+cd redis-3.0
+rg 'sentinelCheckSubjectivelyDown|sentinelAskMasterStateToOtherSentinels|sentinelFailoverStateMachine' src/sentinel.c该切片固定Redis 3.0分支、编译器、配置、数据集和命令序列;先保存结构或函数位置,再运行隔离实例。任何持久化损坏、断线、故障转移、大键或高流量实验都必须使用临时数据并规定CPU、内存、磁盘、延迟和停止上限。
unit: rdi-16-sentinel
source_file: sentinel.c
axis_a: "故障认定"
axis_b: "选举状态"
fault: "把单个Sentinel的主观下线当成客观下线,或未获多数就执行切换"
invariant: "故障判断满足法定票数,单轮只有合法领头者,晋升后旧主被重配置且客户端拓扑最终一致"
replay: same_version_same_input三个必须主动触发的误区
误区 1
现象 → 哨兵只部署一个 原因 → 单点误判与故障 修法 → 至少三哨兵跨机部署
误区 2
现象 → 超时设得太敏感 原因 → 抖动引发频繁切换 修法 → down-after 适度放宽
误区 3
现象 → 客户端不更新路由 原因 → 切换后仍写旧主 修法 → 客户端接入哨兵发现机制
小结
- 哨兵监控主从健康状态
- 主观与客观下线两阶段
- 选举领头哨兵执行故障转移
- 客户端通过哨兵发现新主
- 哨兵集群自身也要高可用
练习、答案与节点验证
练习
问题 1: 主观下线与客观下线的区别?
问题 2: 领头哨兵如何选择新主库?
问题 3: 设计三哨兵部署并说明 quorum 设置理由。(独立实现)
术语复核与本章回顾
完成第16章 Sentinel意味着能从sentinel.c解释沿Sentinel初始化、INFO发现、hello频道、主客观下线、领头选举与故障转移还原高可用,能运行章专属状态实验,能制造反例并在复位后证明旧状态没有残留。