哨兵健康检查必须用sentinel get-master-addr-by-name查哨兵认定的主库地址并ping,不可直连原主库;需轮询所有哨兵节点、超时≤2秒;主从切换应监听notify-script而非轮询;区分+sdown(仅日志)与+odown(触发告警及选主验证);python监控应弃用redis-py sentinel类,改用subprocess调redis-cli严格校验返回码和stderr。

哨兵节点健康检查必须用 SENTINEL GET-MASTER-ADDR-BY-NAME
直接连主库做 PING 会漏判:主库可能存活但已失联哨兵,或被降级为从库。真正要确认的是“当前被哨兵认定的主库是否可连”,所以必须走哨兵协议查状态。
实操建议:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 对每个哨兵节点单独执行
SENTINEL GET-MASTER-ADDR-BY-NAME <master-name></master-name>,不能只查一个哨兵——哨兵间状态同步有延迟,单点判断不可靠 - 超时设为
2秒以内,redis-cli -t 2 -s /var/run/redis/sentinel.sock SENTINEL GET-MASTER-ADDR-BY-NAME mymaster比 TCP 连接更轻量 - 返回
(nil)或报错NOGOODSLAVE都算异常,不是只有空响应才需告警
主从切换事件必须监听 SENTINEL NOTIFY-SCRIPT 而非轮询
轮询 SENTINEL MASTER mymaster 查角色变化,延迟高、负载重,且无法捕获瞬时切主(比如主库闪断后快速恢复,哨兵又切回原主)。
实操建议:
- 在哨兵配置里启用通知脚本:
sentinel notify-script mymaster /etc/redis/failover-handler.sh - 脚本接收 4 个参数:
$1(事件名,如+switch-master)、$2(主名)、$3(旧主地址)、$4(新主地址),别依赖STDIN - 脚本内立刻记录时间戳和地址,再异步触发下游动作(如更新 DNS、刷新客户端缓存),避免阻塞哨兵进程
监控脚本必须区分 +sdown 和 +odown 两类主观/客观下线事件
+sdown 是单个哨兵认为实例不可达,+odown 是多数哨兵达成共识——后者才真正触发故障转移。混用会导致误告警或漏告警。
实操建议:
- 用
SENTINEL SENTINELS <master-name></master-name>查当前投票数,确认quorum是否满足,比单纯看日志更可靠 - 收到
+sdown时只记日志,不发告警;收到+odown立即检查SENTINEL GET-MASTER-ADDR-BY-NAME结果,验证是否已开始选主 - 注意:从库上报
+sdown不影响主库可用性,但若连续 3 个哨兵都报同一从库+sdown,说明网络分区可能已发生
Python 脚本调用哨兵命令时避免用 redis-py 的 Sentinel 类
redis.sentinel.Sentinel 内部会维护连接池并尝试自动重试,但在监控场景下反而掩盖真实问题:比如哨兵进程僵死但 TCP 连接未断,它仍返回旧缓存结果。
实操建议:
- 改用
subprocess.run直接调redis-cli,控制超时和退出码,例如:result = subprocess.run(['redis-cli', '-s', '/tmp/sentinel.sock', 'SENTINEL', 'MASTER', 'mymaster'], capture_output=True, timeout=3)
- 检查
result.returncode != 0和b'ERR' in result.stderr两个条件,缺一不可——有些错误只写 stderr 不设 exit code - 不要复用 socket 文件路径,每个哨兵实例应配独立 sock 路径,否则并发调用会冲突
mv 替换临时文件),否则切主瞬间的日志丢失会导致状态错乱。










