先确认是否进入客观下线(+odown):执行sentinel masters检查flags是否含odown;若仅+sdown,说明未达成quorum共识,需用sentinel sentinels 和sentinel ckquorum验证哨兵连通性与法定票数。

主节点死机后哨兵迟迟不选举,大概率不是“慢”,而是卡在某个前置环节没推进下去——先确认是否真进入了客观下线(+odown),再查有没有可用从节点、有没有足够哨兵参与投票。
怎么快速确认是否已进入客观下线
主观下线(+sdown)只是单个哨兵的判断,不触发任何切换;必须看到 +odown 日志才算真正启动故障转移流程。
- 登录任意一台哨兵,执行
SENTINEL masters,检查输出中flags字段是否含odown(不是sdown或空) - 若只有
sdown,说明其他哨兵还没达成共识:用SENTINEL sentinels <master-name></master-name>查看在线哨兵数,再运行SENTINEL ckquorum <master-name></master-name>确认是否满足quorum值 - 常见假象:日志里反复出现
+sdown但无+odown→ 很可能某台哨兵被防火墙隔离、NTP 时间偏移超 5 秒、或sentinel monitor配置未同步(比如新哨兵刚启动不到 30 秒)
为什么 SENTINEL masters 显示 num-slaves=0 或全是 odown
哨兵判定主节点 odown 后,下一步是找活着的从节点来接班。如果 num-slaves 是 0,说明它根本“看不见”任何从节点——不是挑不出,是压根没连上。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 逐台登录每个从节点机器,执行
redis-cli -p 6379 INFO replication,重点核对三行:role:slave、master_link_status:up、master_host指向当前故障主库 - 若
master_link_status:down,说明从节点自己早就断开了复制,哨兵会直接跳过它;此时再看master_last_io_seconds_ago是否大于down-after-milliseconds(默认 30000) - 检查从节点 Redis 配置:
bind是否绑定了0.0.0.0(而非仅127.0.0.1),protected-mode是否为no,requirepass是否配了对应sentinel auth-pass - 用
telnet <slave-ip> 6379</slave-ip>从哨兵机器直连测试,确认 TCP 层通不通——防火墙拦端口比配置错误更隐蔽
quorum 和哨兵存活数不匹配导致投票卡死
quorum 不是哨兵总数,而是“最少几个哨兵同意才能发起故障转移”。设成 2 却只有 1 台哨兵能通信,SENTINEL ckquorum 会直接报 missing+quorum,后续流程全部冻结。
- 执行
SENTINEL sentinels <master-name></master-name>,确认返回的哨兵列表是否完整;若某台长期失联,它的flags会含disconnected或odown - 检查所有哨兵机器的
26379端口是否双向开放(不仅是入站),且 NTP 时间同步误差 - 不要只改
sentinel.conf文件,必须在每台哨兵上执行SENTINEL monitor <name><ip><port><quorum></quorum></port></ip></name>强制刷新视图,否则新哨兵可能缓存旧配置 - 生产环境建议部署 3 或 5 个哨兵(奇数),
quorum设为2或3,避免偶数 quorum 在网络分区时分裂投票
Lettuce 客户端卡在旧连接导致“切换完成但业务没感知”
哨兵日志里已出现 +switch-master,但 Spring Boot 应用仍往旧地址发请求——这不是哨兵没切,是客户端连接池没刷新地址。
- Lettuce 默认启用 DNS 缓存和连接池地址缓存,对哨兵事件响应迟钝;尤其当配置了短超时(如
timeout=600)时,旧连接 hang 住不释放 - 验证方式:在应用机器上用
redis-cli -h <old-master-ip> -p 6379 PING</old-master-ip>,若返回NOAUTH Authentication required或直接拒绝,说明旧主已降级,问题出在客户端 - 修复方案:升级 Lettuce 到 6.3+,启用
DynamicRedisClient或手动监听__sentinel__:hello频道;或临时调大client-output-buffer-limit防止缓冲区溢出中断连接 - 注意:Jedis 默认不支持自动重连哨兵,必须配合
JedisSentinelPool且设置合理maxWaitMillis
真正卡住选举的,往往不是算法本身,而是网络连通性、配置同步、时间一致性这些底层细节。别急着调 failover-timeout,先确保哨兵能互相说话、能连上从节点、能读到从节点真实的 INFO replication 输出——这三步走不通,后面全是空谈。










