Redis Sentinel 故障转移怎样判断主节点已切换
来源:17golang原创
时间:2026-11-02 08:00:21 496浏览 收藏
Redis Sentinel 故障转移后,最容易误判的地方是“查到了一个新地址”就认为切换完成。更稳妥的判断是把三类信息放在一起:Sentinel 通过 master-name 返回的当前主节点地址、目标 Redis 实例报告的角色,以及 Sentinel 记录的配置纪元。三者一致,才适合让客户端更新连接目标。
官方地址:https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/
实战中先查 Sentinel,再连接它返回的地址读取ROLE或INFO replication,最后对照多个 Sentinel 的视图和config-epoch。只看旧主节点是否恢复、只看一个 Sentinel,或者只看客户端重连成功,都不足以证明主节点已经切换。
先把判断对象限定为同一个 master-name
Sentinel 监控的是一个逻辑主节点名,例如 mymaster,而不是客户端自己起的业务别名。排查时先确认应用配置里的名称与 Sentinel 配置中的名称相同;名称错了,后面的地址、角色和纪元都会变成另一组数据。
这一步的目标不是判断切换,而是保护判断链路的输入。故障转移期间不要把旧主节点的 IP 固定写回应用配置,也不要把某个 Sentinel 的端口误当成 Redis 数据端口。
先查 Sentinel 认为的当前主节点
SENTINEL get-master-addr-by-name 会按照 master-name 返回当前主节点的地址。返回的两行通常分别是 IP 或主机名、端口;它适合回答“客户端下一步应该找谁”,但单独不能回答“切换是否已经完全收敛”。
# 用监控名称查询 Sentinel 当前记录的主节点地址
redis-cli -h 192.0.2.10 -p 26379 SENTINEL get-master-addr-by-name mymaster
# 查看该 master 的状态字段,重点关注 flags、ip、port 和 config-epoch
redis-cli -h 192.0.2.10 -p 26379 SENTINEL master mymaster

重点记录四个值:查询使用的 master-name、返回的当前主节点 IP、当前主节点端口,以及 SENTINEL master 中的 config-epoch。如果多个 Sentinel 返回的地址不同,先把状态记为“视图尚未收敛”,不要急着改客户端。
用角色和纪元确认切换已经完成
拿到 Sentinel 返回的地址后,直接访问这个 Redis 实例,确认它报告自己是主节点。ROLE 的第一个元素可以表明实例角色,INFO replication 则能补充当前复制关系。这里要看的是目标实例本身的状态,不是客户端连接池里残留的旧连接。
# 连接 Sentinel 返回的目标地址,读取实例自报角色
redis-cli -h 192.0.2.21 -p 6379 ROLE
# 查看复制关系,确认目标实例是否已经成为 master
redis-cli -h 192.0.2.21 -p 6379 INFO replication
可以按下面的证据组合判断:
- Sentinel 返回的地址是新地址,目标实例
ROLE的角色为master:说明新主节点已经具备主角色。 - 旧地址的
ROLE变为slave或replica,并指向新主节点:说明旧主节点已经被纳入新的复制关系。 - Sentinel 的
config-epoch相比切换前发生推进,多个 Sentinel 最终看到同一地址:说明控制面状态正在收敛。

注意,config-epoch 是 Sentinel 用来区分配置版本的控制面信息,不等同于业务数据已经同步到某个时间点。它能帮助判断“哪一套主节点视图更新”,不能替代数据一致性检查。
多个 Sentinel 不一致时怎样分级处理
我在排查时会把结果分成三档,而不是把所有异常都叫作“切换失败”。
| 观察到的组合 | 判断 | 处理建议 |
|---|---|---|
| 多个 Sentinel 同一地址,目标角色为 master | 切换证据完整 | 让客户端按 Sentinel 重新获取地址,清理旧连接 |
| 地址已相同,但目标角色仍未变为 master | 实例状态尚未收敛 | 暂缓宣布完成,继续读取角色和复制关系 |
| 不同 Sentinel 返回不同地址或纪元 | 控制面视图不一致 | 检查 Sentinel 间连通性、仲裁状态和时间点记录 |
如果应用重连成功但业务仍然写入旧实例,通常说明连接池没有真正刷新,或代码把首次解析到的地址缓存成了永久配置。Sentinel 的职责是提供当前主节点视图,客户端仍需要支持重新解析、断开旧连接和重试策略。
客户端切换时要保留哪些证据
为了让下一次复盘能还原判断,不必保存完整日志,只需在同一时间窗口记录:查询的 Sentinel 地址、master-name、返回的 IP/端口、ROLE 首字段、INFO replication 中的角色摘要、runid(若返回)和 config-epoch。这些字段足以区分“找到了新地址”和“新地址已经成为主节点”。
// 只把 Sentinel 返回的地址当作候选连接目标,不把旧地址永久写死。
func shouldSwitch(sentinelAddr, masterName, role string) bool {
// 角色判断只回答目标实例当前是否为 master,地址仍应由 Sentinel 查询得到。
return sentinelAddr != "" && masterName != "" && role == "master"
}
这段判断只是连接层的最小边界示意,真实客户端还应处理超时、连接池清理和重试退避。不要把“函数返回 true”当成 Redis 已经完成数据同步的证明。
常见问题
只执行 SENTINEL get-master-addr-by-name 可以吗?
它适合获取当前连接目标,但不够证明切换完成。至少再读取目标实例角色,并在多个 Sentinel 之间对照地址和配置纪元。
旧主节点恢复后为什么不能继续使用旧地址?
故障转移后旧实例可能已经变成副本。客户端应遵循 Sentinel 的当前主节点视图,不能因为旧地址重新可连接就把写请求发回去。
config-epoch 越大是否代表数据一定更新?
不是。它用于区分 Sentinel 的配置版本;数据复制进度仍应通过实例角色、复制关系和业务侧可接受的一致性策略单独判断。
总结一下:先用同一个 master-name 查询 Sentinel 当前地址,再对目标实例读取 ROLE 或 INFO replication,最后用多个 Sentinel 的地址和 config-epoch 做交叉判断。这样确认的是一条可复盘的切换证据链,而不是某个瞬间的连通性。
-
490 收藏
-
378 收藏
-
367 收藏
-
288 收藏
-
430 收藏
-
278 收藏
-
404 收藏
-
212 收藏
-
114 收藏
-
266 收藏
-
280 收藏
-
474 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习