一、前言:主节点宕机后,系统如何“自救”?
在 Redis 主从 + 哨兵架构中,主节点(Master)一旦宕机,写服务将立即中断。
若依赖人工干预,恢复时间可能长达数分钟,严重影响用户体验与业务 SLA。
Redis 哨兵集群的核心价值,就在于它能实现“无人值守”的自动故障恢复。
本文将带你逐帧拆解故障恢复的全过程:
✅ 从主节点宕机检测
✅ 到 Sentinel 共识达成
✅ 再到新主选举与配置重定向
✅ 最终客户端无感切换
掌握这些,你就能真正理解 Redis 高可用背后的“智能大脑”。
二、故障恢复全景流程图
整个故障恢复过程可分为 5 个阶段:

下面我们将逐一详解每个阶段的内部机制。
三、阶段 1:主节点宕机检测 —— 主观下线(SDOWN)
3.1 触发条件
- 主节点进程崩溃、机器断电、网络隔离等导致无法响应
- 每个 Sentinel 独立向主节点发送 PING 命令(默认每秒 1 次)
3.2 判定逻辑
sentinel down-after-milliseconds mymaster 30000
- 若连续 30 秒 未收到有效响应(如 +PONG、-LOADING 等),Sentinel 将其标记为 主观下线(SDOWN)
⚠️ 注意:
- SDOWN 是本地状态,仅当前 Sentinel 认为节点不可用
- 不会触发故障转移!
四、阶段 2:集群共识 —— 客观下线(ODOWN)
单点判断不可靠,需集群达成共识。
4.1 Gossip 信息交换
- Sentinel 节点之间通过 Gossip 协议 每 2 秒交换彼此的观测结果
- 消息内容包括:<主节点地址, 状态, runid, offset>
4.2 客观下线(ODOWN)判定
sentinel monitor mymaster 192.168.1.100 6379 2
# ↑
# quorum = 2
- 当 ≥ quorum 个 Sentinel 认为主节点 SDOWN 时,集群将其标记为 客观下线(ODOWN)
🔑 关键点:
- quorum 是 ODOWN 的门槛值,不是多数派
- 但后续 Leader 选举仍需多数派(> N/2)
示例(3 节点 Sentinel):
- Sentinel1、Sentinel2 均报告 SDOWN → 数量 = 2 ≥ quorum(2) → 触发 ODOWN
五、阶段 3:Leader 选举 —— 谁来执行故障转移?
ODOWN 后,需选出一个 Sentinel 作为 协调者(Leader) 执行故障转移。
5.1 选举机制(基于 Raft 简化版)
- 若自己未投票,且请求合法 → 投赞成票
✅ 举例:3 节点集群 → 需 ≥ 2 票才能当选
5.2 为什么需要 Leader?
- 避免多个 Sentinel 同时执行故障转移 → 导致多主脑裂
- 确保故障转移操作原子性与一致性
六、阶段 4:执行故障转移 —— 6 步完成主从切换
Leader Sentinel 按以下步骤完成故障恢复:
步骤 1️⃣:选择新主节点
从所有健康从节点中,按优先级排序:
📌 假设选出 Slave1 作为新主。
步骤 2️⃣:升主(Promote to Master)
向 Slave1 发送命令:
SLAVEOF NO ONE
→ Slave1 断开与原主的复制关系,成为独立主节点。
步骤 3️⃣:重配其他从节点
向剩余从节点(如 Slave2)和原主节点(若恢复) 发送:
SLAVEOF <new_master_ip> <new_master_port>
→ 所有从节点指向新主,形成新主从拓扑。
步骤 4️⃣:更新 Sentinel 配置
- 所有 Sentinel 更新内存中的主节点信息
- 持久化到 sentinel.conf(自动重写配置文件)
步骤 5️⃣:通知客户端
- 客户端可通过两种方式感知变更:
- 主动查询:SENTINEL get-master-addr-by-name mymaster
- 事件订阅:监听 +switch-master Pub/Sub 通道
步骤 6️⃣:原主节点恢复处理
- 原主重启后,自动变为从节点,同步新主数据
- 不会抢回主身份(避免震荡)
七、阶段 5:客户端无感切换
现代 Redis 客户端(如 Jedis、Lettuce、Spring Data Redis)均支持 Sentinel 模式:
Java(Jedis 示例)
Set<String> sentinels = Set.of("s1:26379", "s2:26379", "s3:26379");
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);
// 自动获取当前主节点
try (Jedis jedis = pool.getResource()) {
jedis.set("key", "value"); // 写入新主
}
✅ 优势:
- 应用无需重启
- 连接池自动刷新主节点地址
- 切换期间短暂异常可重试
八、关键配置参数与调优建议
| down-after-milliseconds | SDOWN 超时 | 10~30 秒(根据网络质量) |
| quorum | ODOWN 门槛 | 3 节点设 2,5 节点设 3 |
| failover-timeout | 故障转移总超时 | ≥ 60 秒(含升主、重配) |
| parallel-syncs | 并行同步从节点数 | 1~2(避免新主压力过大) |
| slave-priority | 从节点升主优先级 | 关键节点设更低值(如 50) |
九、常见故障恢复问题排查
❌ 问题 1:故障转移未触发
- 原因:Sentinel 节点数 < quorum,或网络分区
- 排查:SENTINEL MASTER mymaster 查看 flags 是否含 odown
❌ 问题 2:切换后客户端仍连旧主
- 原因:客户端未使用 Sentinel 模式,或缓存了旧地址
- 方案:确保使用 JedisSentinelPool 或 Spring Boot Sentinel 配置
❌ 问题 3:原主恢复后变成“双主”
- 原因:原主未正确执行 SLAVEOF new_master
- 检查:查看原主日志是否收到 SLAVEOF 命令
十、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

