哨兵判定主节点宕机需满足两步:先由单个哨兵在down-after-milliseconds内未收到PING/INFO响应标记为SDOWN;再由至少quorum个哨兵达成一致升级为ODOWN,方可触发故障转移。

哨兵判定主节点宕机的条件是什么
哨兵不会一发现主节点没响应就立刻切换,它分两步走:SDOWN(主观下线)和ODOWN(客观下线)。单个哨兵在down-after-milliseconds时间内收不到主节点的PING或INFO响应,就标记为SDOWN;只有当至少quorum个哨兵都报告该主节点SDOWN,才会升级为ODOWN,这时才真正触发故障转移。
常见坑点:
-
quorum值设得太小(比如1),网络抖动就可能误判导致脑裂 -
down-after-milliseconds设得太短(如2000ms),在高延迟网络里频繁误标SDOWN - 哨兵数量为偶数(如2个),
quorum=2时只要一个哨兵失联,就永远凑不够法定人数,无法达成ODOWN
redis-py客户端如何自动感知新主节点
客户端不主动轮询哨兵,就永远连不上新主。关键在于用SentinelConnectionPool,而不是直接连某个固定地址。它会在每次获取连接前调用sentinel.master_for()查最新主节点地址,并缓存结果(默认缓存30秒)。
实操要点:
- 初始化时必须传入全部哨兵地址,例如
sentinels=[('10.0.1.10', 26379), ('10.0.1.11', 26379)] - 避免手动拼接
redis://连接串——那会绕过哨兵发现逻辑 - 如果业务对切换延迟敏感,可调小
socket_timeout和retry_on_timeout,但别设成0 - 务必确认你的
redis包版本≥4.0.0,旧版redis-py对哨兵的支持有缺陷
故障转移后从节点为什么没自动重连新主
哨兵完成切换后,会向所有从节点发送SLAVEOF 命令。但如果从节点配置了requirepass而哨兵没配sentinel auth-pass,这条命令就会被拒绝,导致从节点卡在旧主地址上,形成数据断层。
必须同步检查的三项配置:
- 主节点密码是否一致:从节点
masterauth要和原主节点requirepass相同 - 哨兵配置中是否声明了密码:
sentinel auth-pass mymaster - 哨兵自身是否能连上带密码的主从节点(可通过
redis-cli -a验证)-p 26379 ping
旧主恢复后为什么变成“只读副本”却不再同步
这是哨兵的默认行为:旧主节点重新上线后,哨兵会自动执行SLAVEOF 把它降级为从节点。但如果此时新主节点的replica-announce-ip没配对(比如新主在Docker内网,对外暴露的是宿主机IP),旧主尝试连接时就会超时失败,最终停留在connecting状态,日志里反复出现Connecting to MASTER但无后续。
根本原因往往藏在这几个地方:
- 新主节点的
bind和replica-announce-ip不匹配,导致其他节点看到的IP不可达 - 防火墙或安全组没放开新主节点的
6379端口入站流量 - 旧主节点的
slaveof命令被拒绝,错误日志里藏着NOAUTH Authentication required但没人看
切换本身很快,真正卡住的往往是这些配置细节。一旦涉及跨网络、容器或云环境,replica-announce-ip和bind的组合必须手工核对,不能依赖默认值。











