哨兵选主失败或频繁切换的根本原因是时钟偏差过大或网络单向隔离;需先用ntpstat和chronyc tracking检查时钟同步,再用tcpdump验证26379端口双向通信,最后才调整哨兵参数。

哨兵选主失败或频繁切换的典型现象
业务连接突然报 NOAUTH Authentication required 或 READONLY You can't write against a read only replica,但 Redis 实例本身没挂;或者客户端日志里反复出现 Connection refused 后又自动恢复——这往往不是 Redis 崩了,而是哨兵(Sentinel)在反复执行故障转移,新主刚切完就被判定“失联”,又切回去,形成震荡。
根本原因常藏在两个地方:服务器之间时钟偏差过大,或网络存在单向隔离(比如防火墙只放行了主→从的端口,没放行从→主的 SENTINEL is-master-down-by-addr 请求)。
用 ntpstat 和 chronyc tracking 快速确认时钟同步状态
Redis 哨兵依赖时间戳做主观下线(sdown)和客观下线(odown)判断。若各节点时间差超过 down-after-milliseconds(默认 30000ms),哨兵可能把健康实例误判为宕机。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 在每台 Sentinel 和 Redis 节点上运行
ntpstat:如果输出是synchronised to NTP server,且 offset 在 ±50ms 内,基本安全;若显示unsynchronised,立刻排查 NTP 配置 - 用
chronyc tracking查更细粒度数据:System time offset字段超过 ±100ms 就要干预;Leap status显示Not synchronised表示已脱网 - 别只看本地
date输出——它不反映 NTP 同步质量;也别只校准一次,得持续监控,因为虚拟机在宿主机资源紧张时容易发生时钟漂移
用 tcpdump 抓包验证哨兵间通信是否被网络策略阻断
哨兵靠 TCP 端口(默认 26379)互相交换 is-master-down-by-addr、sentinel is-master-down-by-addr 等命令。一旦某台哨兵收不到足够数量的“同意下线”响应,就无法触发客观下线,导致反复试探、超时重试,最终引发无效选主。
- 在任意两台哨兵节点上同时执行:
tcpdump -i any port 26379 -w sentinel.pcap,然后手动触发一次SENTINEL failover,再比对双方抓包中是否有对应请求/响应的往返 - 重点检查:源 IP 是否被目标防火墙 DROP;TCP SYN 包发出后是否收到 SYN-ACK;是否存在大量重传(
tcpdump中显示[TCP Retransmission]) - 常见陷阱:云厂商安全组默认只允许入方向,哨兵集群必须配置双向放行;K8s Service 的 headless 模式下,DNS 解析到的 Pod IP 可能因网络插件未打通跨节点通信而丢包
调整哨兵配置前先验证时钟与网络的真实状态
很多人一遇到频繁选主,第一反应是调大 down-after-milliseconds 或 quorum,结果只是掩盖问题——时钟不同步或网络隔离没解决,延迟只会越来越高,直到某个节点彻底掉出法定票数,故障转移彻底失效。
真正该做的顺序是:先用 ntpstat 和 chronyc tracking 锁定时钟偏差来源(NTP 服务器不可达?VMware Tools 时间同步被禁用?);再用 tcpdump 确认哨兵间 26379 端口的四层连通性;最后才考虑调整哨兵参数。否则改来改去,还是在抖动。

















