Redis 09 · 高可用:Sentinel 如何发现故障并完成切主

主从复制让副本拥有数据,但主节点宕机后,谁来判断故障、选择新主,并让客户端找到它?这正是 Sentinel 解决的问题。它不是复制协议的替代品,而是建立在主从复制之上的监控、通知和自动故障转移组件。

目录

  1. [Sentinel 的职责边界](#Sentinel 的职责边界)
  2. 主观下线与客观下线
  3. 故障转移的完整流程
  4. [Leader 选举与从节点晋升](#Leader 选举与从节点晋升)
  5. 客户端重连与配置传播
  6. 生产配置与演练

一、Sentinel 的职责边界

Sentinel 监控主节点、副本和其他 Sentinel,提供通知、配置发现和自动故障转移。数据复制仍由主从复制完成,槽位路由则属于 Cluster。

1.1 为什么至少三个 Sentinel

单个 Sentinel 自己挂掉就失去判断能力。多个 Sentinel 通过投票确认故障,通常部署在三个独立故障域,避免一台机器或一个可用区的故障阻断选主。

1.2 三类连接

Sentinel 会周期性向 Redis 发送 PING,并通过发布订阅频道发现其他 Sentinel;客户端则从 Sentinel 查询当前主节点地址,而不是永久写死某个 IP。

二、主观下线与客观下线

单个 Sentinel 在 down-after-milliseconds 内收不到有效响应,会把实例标记为主观下线(SDOWN)。这只是"我认为它有问题"。

随后它向其他 Sentinel 询问同一实例状态。当达到 quorum 的 Sentinel 都认为不可达,才升级为客观下线(ODOWN),允许启动故障转移。

网络分区时尤其要谨慎:少数分区可能看不到主节点,但多数 Sentinel 所在分区仍能通信。quorum 不是集群总人数,不能脱离部署拓扑孤立理解。

三、故障转移的完整流程

流程可以压缩成:发现故障 → 选出 Leader → 选择副本 → 晋升 → 重配其他副本 → 发布新主地址。

主节点恢复后不会自动夺回主身份,而是作为新主的副本重新同步,避免"双主写入"。客户端必须能处理连接断开、重试和命令幂等。

四、Leader 选举与从节点晋升

参与故障转移的 Sentinel 先进行 Raft 风格的 Leader 选举。候选人需要获得多数 Sentinel 的授权,授权带有纪元,避免旧选举结果覆盖新状态。

副本选择会综合优先级、复制 offset、运行 ID 等信息。配置了 replica-priority 0 的副本不会被选为新主;更接近主节点 offset 的副本通常数据更新。

五、客户端重连与配置传播

客户端应使用 Sentinel 的服务名查询主节点,并监听 +switch-master 等事件。切主窗口内,旧连接可能收到 READONLY、连接拒绝或超时,应用层要设计退避和幂等重试。

Sentinel 会向新主和其他副本发送复制配置,也会更新自身对主节点地址的认知。DNS、连接池和服务发现缓存的 TTL 过长,会让自动切主看起来"没有生效"。

六、生产配置与演练

sentinel monitordown-after-millisecondsfailover-timeoutparallel-syncs 需要结合网络延迟、数据量和恢复目标设置。不要把超时时间压到低于正常尖峰的 RTT。

演练至少覆盖:主节点进程崩溃、网络隔离、慢磁盘、客户端连接池重建和旧主恢复。记录从故障发生到客户端恢复写入的完整时间,而不是只看 Sentinel 日志中的"切主成功"。

6.1 场景:秒杀主节点假死,为什么 30 秒后还在报错

某次秒杀时,product:stock:1001 的写入持续升高,主节点没有崩溃,却因为磁盘抖动和慢命令积压,PING 在一段时间内无法及时处理。三个 Sentinel 陆续将它标成 SDOWN,随后满足 quorum,故障转移完成;但应用仍连续报 30 秒写超时。

排查不能停在"Sentinel 已经切主"。按时间线看:检测耗时由 down-after-milliseconds 决定,选举与晋升需要数秒;更关键的是应用连接池仍持有旧主连接,第一次失败后没有清除连接,也没有重新通过 Sentinel 查询主地址。业务重试又使用了固定 50ms 间隔,数百个线程同时重试,把新主刚恢复的连接队列打满。

处理顺序应当是:先限制秒杀写入口并降低重试并发;确认 SENTINEL get-master-addr-by-name 已返回新主;让客户端主动驱逐旧地址连接并执行带随机抖动的有限重试;最后核查新主的 master_repl_offset 与旧主最后已确认位置,评估极短异步复制窗口内的库存写是否需要按订单事件补偿。

长期配置上,不要把 down-after-milliseconds 盲目调到 1 秒来追求"快切"。它必须大于正常网络尖峰、GC 停顿和 Redis 延迟的组合。切主 RTO 的优化重点通常是客户端发现与连接池重建,而不是压缩故障判定到误切主的程度。

6.2 一份可执行的演练清单

演练前先写清成功标准:例如"主进程 SIGKILL 后 20 秒内 99% 写请求恢复;重复下单不产生重复扣减;旧主恢复后不接受写入"。演练时分别模拟进程退出、仅隔离主节点与 Sentinel 的网络、仅隔离应用到主节点的网络。三者的观察结果不同,只有第一种最像真正宕机。

记录 +sdown+odown+try-failover+switch-master 的时间戳,同时记录应用错误率、连接池活跃连接、重试量和 Redis 复制 offset。一次只验证 Sentinel 日志的演练,无法说明用户请求真正恢复了。

6.3 误切主后的判断

如果业务没有明显故障却发生了切主,优先检查 Sentinel 到 Redis 的网络路径,而不是先调大 quorum。查看 SENTINEL masters 中的 last-ok-ping-replydown-after-millisecondsnum-other-sentinels,再对照节点所在可用区、容器 CPU throttling 与网络丢包。若只有一个 Sentinel 看到超时,正常情况下不应形成 ODOWN;若多数 Sentinel 位于同一故障域,拓扑本身就不抗分区。

恢复旧主时先停止写入,确认它已经执行 REPLICAOF new-master,再观察 master_link_status 和同步 offset。绝不能直接把旧主重新加入并允许它继续写,否则短暂网络分区会演变成双主数据分叉。


记住:复制提供候选数据,Sentinel 提供故障判断和切主,客户端负责重新发现与重试;三者缺一不可。

相关推荐
考虑考虑2 小时前
Redis8.8新特性
运维·redis·后端
BUG研究员_3 小时前
LangGraph节点缓存-CachePolicy
python·缓存·langraph
tryxr4 小时前
Redis 的背景知识
数据库·redis·缓存
莫得感情 o4 小时前
Redis 08 · 主从复制:全量同步、增量同步与复制延迟
redis·缓存
BUG指挥官5 小时前
Redis已接入AI
数据库·人工智能·spring boot·redis·spring cloud
醉颜凉13 小时前
Redis网络层解析:高性能服务器架构设计与实现
redis·epoll·网络架构·i/o多路复用·事件驱动
醉颜凉13 小时前
Redis 与 Pika 对比:大容量冷热数据落盘方案与混合存储架构
redis·pika·混合存储·存储架构·冷热数据分离
刃神太酷啦17 小时前
Redis 进阶核心:持久化 (RDB/AOF)、事务与主从复制全解析----《Hello Redis!》(5)
linux·c语言·数据库·c++·redis·缓存·bootstrap
三84417 小时前
SSRF 打内网 Redis:gopher 原理与实操
redis·web安全·bootstrap·ssrf