Redis 哨兵机制详解:哨兵如何发现彼此、判断故障并完成主从切换
引言
在 Redis 主从架构中,哨兵(Sentinel)承担着故障检测与自动切换的关键职责。然而,多个哨兵节点如何协同工作?它们之间又是如何发现彼此、达成共识的?
本文将从哨兵利用 __sentinel__:hello 频道实现互相感知的机制入手,逐步拆解哨兵集群的完整工作流程,包括:
- 哨兵之间如何发现彼此
- 主观下线和客观下线是怎么判断的
- Leader 哨兵如何选举产生
- 新主库是如何被选出来的
- 切换完成后,其他节点和客户端如何被通知
把这条链路看懂之后,Redis Sentinel 为什么能在不依赖外部组件的情况下实现高可用,就会清楚很多。
哨兵之间如何感知彼此
在 Redis 主从集群中,主库上有一个名为 __sentinel__:hello 的频道,不同哨兵就是通过这个频道相互发现、交换信息的。
可以这样理解:
- 每个哨兵都会定期把自己的信息发布到这个频道
- 其他哨兵会订阅这个频道
- 订阅方收到消息后,就知道当前还有哪些哨兵在共同监控这组主从实例
例如:
- 哨兵 1 把自己的 IP 和端口发布到
__sentinel__:hello - 哨兵 2 和哨兵 3 订阅了该频道
- 哨兵 2 和哨兵 3 收到后,就能感知到哨兵 1 的存在
所以哨兵集群的互相发现,并不是靠额外注册中心完成的,而是 Redis 自身提供的发布订阅机制完成的。
哨兵机制的基本流程
Redis 哨兵机制大致可以拆成四个阶段:
- 监控
- 故障判断
- Leader 选举
- 主从切换与通知
监控过程
哨兵会周期性地给所有主库、从库以及其他哨兵发送 PING 命令,用于检测节点是否存活。
从库故障判断
如果某个从库在规定时间内没有响应,哨兵会把它标记为下线节点。
这个超时时间通常由 down-after-milliseconds 控制,默认常见配置是 30 秒。
主库故障判断
主库的判断会更谨慎。
如果某个哨兵发现主库在 down-after-milliseconds 时间内没有响应,它会先把主库标记为:
- 主观下线(Subjectively Down,简称
sdown)
这里之所以只是“主观下线”,是因为:
- 有可能是这个哨兵自己网络有问题
- 也有可能只是它和主库之间链路异常
所以仅凭单个哨兵的判断,不能直接认定主库真的挂了。
什么是客观下线
如果一个哨兵判断主库主观下线,它会向其他哨兵发起询问:
- 你们是否也认为这个主库不可用了
当足够多的哨兵都认为该主库不可用时,主库才会被标记为:
- 客观下线(Objectively Down,简称
odown)
这个判断通常要求达到配置的法定票数,也就是常说的 quorum。很多资料会简单理解为“半数以上同意”,但更准确地说,是:
- 需要达到 Sentinel 配置中的法定票数要求
只有当主库被判定为客观下线后,后续的故障转移流程才会真正开始。
为什么要区分主观下线和客观下线
主观下线和客观下线的区别,本质上是在解决“误判”问题。
如果没有这层设计,那么:
- 某一个哨兵自己网络波动
- 它误以为主库挂了
- 然后立刻触发切换
系统就会发生错误的主从切换。
所以 Redis Sentinel 的设计是:
- 单个哨兵只能做主观判断
- 多个哨兵形成共识后,才进入客观下线和故障转移
Leader 哨兵是怎么选出来的
当主库被判定为客观下线后,哨兵集群需要选出一个 Leader 哨兵来负责执行故障转移。
注意,这里选举的是:
- 负责本次故障转移的 Leader 哨兵
而不是说“某个哨兵节点本身下线了,再选新的哨兵 leader”。
选举的基本思路
每个符合条件的哨兵都可以发起投票,请求其他哨兵把票投给自己。
整个过程本质上是:
- 哨兵之间相互投票
- 谁先拿到足够多的票,谁就成为本轮故障转移的 Leader
通常可以简单理解为:
- 当某一个哨兵获得超过半数支持时,就可以成为 Leader
哨兵投票过程怎么理解
当主库被判定为客观下线后,各个哨兵会进入 Leader 选举阶段。
此时:
- 每个哨兵都可能发起一次“把票投给我”的请求
- 每个哨兵在一轮选举中通常只会投一票
- 谁先获得足够多的票,谁就负责本轮主从切换
所以这里真正被判定客观下线的是:
- 主库
真正被选举出来的是:
- 负责执行故障转移的 Leader 哨兵
这两个角色不能混在一起。
新主库是怎么选出来的
Leader 哨兵被选出来后,不会随便找一个从库升为主库,而是要按照规则进行筛选和打分。
这个过程通常可以概括为:
- 先筛选
- 再打分
筛选过程
首先要排除明显不合适的从库。
例如:
- 与主库断连时间太长
- 自身状态异常
- 网络状况差
常见判断会参考 down-after-milliseconds * 10 这类阈值。如果某个从库和主库长时间失联,说明它的数据可能不够新,也可能网络状况不稳定,那么它就不适合作为新主库候选者。
打分过程
完成筛选后,Leader 哨兵会对剩余从库进行多轮比较。
第一轮:优先级高的从库优先
Redis 可以通过 replica-priority(老版本也常写作 slave-priority)配置从库优先级。
一般来说:
- 优先级数值越小,优先级越高
优先级更高的从库,会更优先被考虑提升为主库。
第二轮:复制进度更接近旧主库的从库优先
主从复制过程中:
- 主库会记录自己的复制偏移量
- 从库也会记录自身同步到哪里
如果某个从库的复制进度最接近旧主库,说明它的数据通常更完整、更接近最新状态,因此得分更高。
第三轮:运行 ID 更小的从库优先
如果前面几个维度都相同,那么 Redis 会继续比较实例运行 ID 等信息,作为最终决策依据之一。
所以整个选主过程并不是随机的,而是带有明确规则的优先级选择。
主从切换完成后会发生什么
当 Leader 哨兵选定新的主库后,会继续完成后续通知和重配置工作。
主要包括:
通知其他从库
Leader 哨兵会把新主库的信息通知给其他从库,让它们执行:
replicaof
从而改为复制新的主库。
通知客户端
哨兵还会把新的主库连接信息通知给客户端,或者让客户端在下一次获取主库地址时拿到最新结果。
这样客户端后续写请求就会落到新的主库上。
恢复集群复制关系
在完成主从切换后,整个集群会逐步进入新的稳定状态:
- 新主库开始接受写请求
- 其他从库重新挂到新主库下
- 原主库如果恢复,也会被重新配置为从库
Redis 哨兵集群如何选举
很多人会单独问一句:“Redis 哨兵集群到底是怎么选举的?”
如果把整个过程压缩一下,可以这样理解:
- 某个主库先被多个哨兵共同认定为客观下线
- 各个哨兵开始发起 Leader 选举
- 每个哨兵在本轮投票中通常只有一票
- 获得足够多选票的哨兵成为 Leader
- Leader 哨兵负责挑选新主库并完成故障转移
所以选举的目标不是选“长期总负责人”,而是:
- 选出这一次故障转移的执行者
哨兵机制为什么能实现高可用
Redis Sentinel 能实现高可用,核心原因就在于它把几个关键能力组合在了一起:
- 哨兵之间能自动发现彼此
- 主库故障要通过多个哨兵共同确认
- 故障转移由选举出的 Leader 统一执行
- 新主库的选择不是随机,而是基于规则筛选
- 切换完成后,还能自动通知从库和客户端
也正因为有这套完整链路,Redis 在传统主从模式之上,才能进一步具备自动故障恢复能力。
总结
这篇文章可以压缩成几条核心结论:
- 哨兵之间通过主库上的
__sentinel__:hello频道互相发现 - 单个哨兵只能判断主观下线,多个哨兵达成共识后才会形成客观下线
- 主库被判定客观下线后,哨兵集群会选出一个 Leader 负责故障转移
- 新主库的选择遵循“筛选 + 打分”的规则,而不是随机挑选
- 切换完成后,哨兵还会通知其他从库和客户端更新连接关系
如果把这些流程串起来理解,Redis 哨兵机制的核心逻辑其实非常清晰:
“先感知、再判断、后选举、再切换、最后通知。”
如果这篇文章对你有帮助,欢迎继续阅读本系列后续内容。若文中有不准确或需要补充的地方,也欢迎指出。
更多推荐




所有评论(0)