08丨Redis 哨兵集群:哨兵故障后还能完成切换吗?

单个 Sentinel 本身也可能故障,所以生产环境通常部署多个 Sentinel。它们共同监控同一复制组,协商主库是否真正下线,并授权其中一个 Sentinel 执行故障转移。

Sentinel 集群能否完成切换,不只取决于存活数量,还同时取决于两个门槛:判断客观下线所需的 quorum ,以及授权故障转移所需的 Sentinel 多数派。

一、Sentinel 集群解决什么问题

部署多个 Sentinel 主要解决三类风险:

  1. 降低误判:单个 Sentinel 与主库之间的网络故障,不应直接触发切换。
  2. 消除单点:一个 Sentinel 故障后,其他 Sentinel 仍可监控复制组。
  3. 协调切换:多个 Sentinel 通过投票,只授权一个执行者完成一次故障转移。

Sentinel 使用配置纪元和多数派投票约束故障转移,但它不会为业务数据提供强一致提交,也不会代理 Redis 业务流量。各 Sentinel 通过传播新拓扑逐步收敛对当前主库的认识。

二、Sentinel 如何发现完整拓扑

Sentinel 启动时通常只配置一个初始主库地址:

conf 复制代码
sentinel monitor mymaster 10.0.0.10 6379 2

它没有静态配置全部从库和其他 Sentinel 地址,但可以逐步发现整个复制组。

1. 通过主库发现从库

Sentinel 周期性查询主库的复制信息,从返回结果中得到从库地址,再分别连接和监控这些从库。

从库变化后,Sentinel 会重新获取拓扑。因此新增从库通常不需要在每个 Sentinel 中单独登记,但必须保证 Sentinel 能从自己的网络环境访问主从节点公布的地址。

2. 通过 __sentinel__:hello 发现同伴

监控同一主库的 Sentinel 会在该复制组的 Redis 节点上,通过 __sentinel__:hello 频道发布自己的地址、运行 ID、配置纪元和已知主库信息,并接收其他 Sentinel 的 hello 消息。

发现同伴后,Sentinel 会建立直接连接,用于:

  • 询问对方是否也认为主库下线。
  • 请求或授予故障转移投票。
  • 传播主库地址和配置纪元。

因此,hello 频道承担的是成员发现和元数据传播,真正的下线协商与选举请求仍通过 Sentinel 之间的命令连接完成。

3. 自动发现依赖可达地址

在 NAT、容器端口映射、跨网段或多网卡环境中,节点自动公布的地址可能无法被其他成员访问。此时需要正确配置 announce 地址和端口,并验证双向网络可达性。

只验证 Sentinel 能访问主库并不够,还要验证:

  • Sentinel 之间能互连。
  • Sentinel 能访问所有候选从库。
  • 客户端能访问 Sentinel 返回的新主库地址。
  • ACL、密码和 TLS 配置在主库、从库、Sentinel 与客户端之间保持匹配。

三、成员发现与客户端通知不是一回事

Redis 复制组上的 __sentinel__:hello 用于 Sentinel 自身发现。Sentinel 进程还会发布 +sdown、+odown、+elected-leader、+switch-master 等事件,供运维系统或客户端订阅。

例如:

text 复制代码
SUBSCRIBE +switch-master
PSUBSCRIBE *

事件订阅适合:

  • 生成监控告警。
  • 观察故障转移进度。
  • 加速客户端刷新拓扑。

但 Redis Pub/Sub 不保存历史消息。订阅连接断开期间发生的事件不会补发,因此它不能成为客户端发现主库的唯一依据。

客户端应把事件当作"立即刷新"的信号,真正建立连接前仍主动查询:

text 复制代码
SENTINEL GET-MASTER-ADDR-BY-NAME mymaster

然后使用 ROLE 或 INFO replication 验证目标实例确实是当前主库。

四、quorum 与多数派是两个门槛

1. quorum 决定能否形成 ODOWN

单个 Sentinel 先根据 down-after-milliseconds 判断主库主观下线,即 SDOWN。随后它询问其他 Sentinel;当同意主库下线的数量达到 quorum,该 Sentinel 才会把主库标记为客观下线,即 ODOWN。

quorum 是每个主库监控配置的一部分:

conf 复制代码
sentinel monitor mymaster 10.0.0.10 6379 2

这里的 2 表示至少两个 Sentinel 同意,才能形成 ODOWN 判断。

2. 多数派决定能否授权切换

形成 ODOWN 后,还不能立即切换。发起故障转移的 Sentinel 必须在当前配置纪元中获得足够授权。

所需票数至少满足:

text 复制代码
max(quorum, Sentinel 总数的多数派)

多数派按已知 Sentinel 总数计算,而不是按当前仍在线的数量计算。

例如 5 个 Sentinel、quorum = 2,只剩 2 个可用:

  • 两个存活 Sentinel 可以互相确认,仍可能形成 ODOWN。
  • 多数派需要 3 票,无法授权任何 Sentinel 执行故障转移。
  • 结果是"确认主库故障,但不能自动切换"。

这一区分可以避免少数网络分区擅自提升新主库。

五、由哪个 Sentinel 执行故障转移

每次故障转移都使用一个新的配置纪元。候选 Sentinel 请求其他 Sentinel 授权自己执行本轮切换。

核心规则是:

  1. 每个 Sentinel 在同一配置纪元只把票投给一个候选者。
  2. 候选者可以给自己投票。
  3. 获得足够票数的 Sentinel 负责本轮故障转移。
  4. 没有候选者达到门槛时,本轮失败,稍后在新的条件下重试。
  5. 执行者不是永久 Leader,只负责某个主库的一次切换。

网络时序可能让不同 Sentinel 同时参选。先到达的有效请求可能先获得某个投票者的票,因此一次选举可能无人胜出。只要多数派仍可通信,后续重试通常能够产生执行者。

六、Sentinel 故障时能否切换

判断时不能只看"还剩几个",应逐项检查:

Sentinel 总数 quorum 可用数量 能否形成 ODOWN 能否自动切换
3 2 3 可以 可以
3 2 2 可以 可以,2 票构成多数
3 2 1 不可以 不可以
5 2 2 可能可以 不可以,缺少 3 票多数
5 3 3 可以 可以
5 3 2 不可以 不可以

表中的"可以"还假设网络、认证、候选从库状态和地址发现都正常。满足票数只是必要条件,不代表切换一定成功。

七、为什么通常选择 3 个或 5 个 Sentinel

三个 Sentinel 是常见最小生产拓扑:

  • 一个故障后仍有两个,既满足常见 quorum = 2,又构成多数派。
  • 部署和运维成本较低。
  • 可以分布到三个独立故障域。

五个 Sentinel 在 quorum <= 3 且剩余成员互相可达时,可以容忍两个成员故障后继续获得三票多数;如果 quorum 配得更高,仍可能无法形成 ODOWN。节点越多并不一定越好,还会增加连接、状态传播、配置管理和故障域设计成本。

更重要的是物理分布。三个 Sentinel 如果都在同一台宿主机、同一个机架电源或同一故障域内,逻辑上有三票,实际仍可能一起失效。

八、down-after-milliseconds 不能只为减少误判而调大

down-after-milliseconds 过小,会把网络抖动、长时间阻塞或宿主机暂停误判为故障;过大则会延迟真实故障发现,直接拉长业务写中断时间。

它应根据以下数据确定:

  • Sentinel 到 Redis 的网络尾延迟。
  • Redis 主线程最长可接受阻塞时间。
  • 宿主机调度暂停和虚拟化抖动。
  • 业务恢复时间目标 RTO。
  • 故障演练中的实际检测与切换耗时。

所有监控同一主库的 Sentinel 应保持关键配置一致,尤其是下线阈值、认证信息和故障转移参数。配置不一致会让不同成员形成判断的时间差显著扩大。

九、客户端应怎样应对主库切换

支持 Sentinel 的客户端通常执行以下流程:

  1. 配置多个 Sentinel 地址和主库逻辑名。
  2. 从任一可用 Sentinel 查询当前主库。
  3. 连接返回地址并验证角色。
  4. 连接断开、收到只读错误或角色不符时,废弃旧连接。
  5. 再次查询 Sentinel,而不是持续重连旧 IP。
  6. 对可重试写入使用请求 ID、幂等键或业务去重。
  7. 使用有界退避和总超时,避免所有客户端同时重连。

故障期间的写请求不能仅放在进程内存中便立即向业务返回成功。只有在请求已进入可靠、可恢复的持久化队列,并且业务语义允许异步完成时,才可以提前确认。

即使新主库已经产生,旧主库上"执行成功但响应丢失"的请求也可能处于不确定状态,因此重试逻辑必须考虑重复执行。

十、部署与安全要点

  • Sentinel 应跨独立宿主机或可用区部署。
  • 不要与同一 Redis 数据节点绑定为完全相同的故障命运。
  • 使用 ACL 限制 Sentinel 和业务客户端权限。
  • 保护 Sentinel 端口,避免暴露到不可信网络。
  • 确保 Sentinel 配置文件目录可写,因为 Sentinel 会持久化新拓扑和配置纪元。
  • 使用主机名时验证解析稳定性;使用容器时验证 announce 地址可达。
  • 对 Sentinel 自身做进程存活、网络、配置重写和时钟异常监控。

Sentinel 不管理 Redis Cluster。Redis Cluster 使用自身的集群总线、分片和故障转移协议。

十一、如何检查 Sentinel 集群状态

常用命令:

text 复制代码
SENTINEL MASTER mymaster
SENTINEL REPLICAS mymaster
SENTINEL SENTINELS mymaster
SENTINEL CKQUORUM mymaster
SENTINEL GET-MASTER-ADDR-BY-NAME mymaster

检查重点:

  • 每个 Sentinel 看到的主库地址是否一致。
  • num-other-sentinels 是否符合部署预期。
  • quorum 与当前可达多数派是否同时满足。
  • Sentinel 是否持续发现全部从库。
  • config-epoch 是否在切换后收敛。
  • 是否出现重复 +sdown/-sdown、故障转移中止或认证错误。
  • SENTINEL CKQUORUM 是否同时通过 quorum 与多数派检查。

十二、哨兵集群检查清单与答案

1. Sentinel 只配置主库地址,是否需要手工配置全部同伴?

**通常不需要。**Sentinel 会通过复制组上的 hello 消息发现监控同一主库的其他 Sentinel,并通过主库复制信息发现从库。

2. 5 个 Sentinel、quorum = 2,只剩 2 个时能否自动切换?

**不能。**两个成员可能形成 ODOWN,但执行故障转移需要 5 个 Sentinel 的多数票,也就是至少 3 票。

3. quorum = 1 是否能让两个 Sentinel 容忍一个故障?

**不能。**形成 ODOWN 可能只需一票,但故障转移授权仍需要两个 Sentinel 的多数,即 2 票。

4. Sentinel 越多是否切换越可靠?

**不一定。**数量必须与故障域、网络和多数派设计匹配。大量共处同一故障域的 Sentinel 并不能提供真正独立的容错能力。

5. 客户端收到 +switch-master 后是否可以永久信任该地址?

**不可以。**事件可能丢失或已经过期。客户端应重新查询主库并验证角色。

6. 增大 down-after-milliseconds 是否只有好处?

**不是。**它可以减少短抖动误判,也会延迟真实故障发现并扩大服务中断窗口。

7. 达到多数票是否表示故障转移一定成功?

**不表示。**还可能因为没有合格从库、认证失败、网络不可达、配置无法重写或从库提升失败而中止。

十三、核心结论

Sentinel 集群的工作链路可以概括为:

  1. 发现:通过复制信息发现从库,通过 hello 频道发现其他 Sentinel。
  2. 判断:单节点形成 SDOWN,达到 quorum 后形成 ODOWN。
  3. 授权 :候选 Sentinel 获得 max(quorum, 多数派) 的票数。
  4. 切换:提升从库、重配复制关系并传播新主库地址。
  5. 重连:客户端主动查询、验证角色并以幂等方式恢复请求。

所以,"还剩下足够形成 quorum 的 Sentinel"并不等于"还能自动切换"。生产设计必须同时满足 ODOWN 门槛、多数派授权、独立故障域、候选从库健康和客户端重发现这五个条件。

相关推荐
盛世宏博智慧档案2 小时前
档案库房温湿度采集数据存储方案:时序数据库选型与存储优化
数据库·时序数据库
SatanII2 小时前
MySQL 数据库学习总结|理论 + SQL 实训完整笔记
数据库·学习·mysql
oradh2 小时前
Oracle 索引深度解析(从内部原理到实战案例)
数据库·oracle
挖掘狂人2 小时前
Redis 正式接入 AI:当"最懂速度的数据库"开始解决"记忆问题"
人工智能·redis·后端
Yyyyyy~2 小时前
[Mysql] 数据类型
数据库·mysql
FITA阿泽要努力2 小时前
第 1 周·第 3 讲|工具如何交给模型:工具定义、参数与结构化调用
服务器·数据库·python·agent
阿标在干嘛2 小时前
缓存架构的“场景适配“:我们为什么在部分服务中采用了本地缓存?
缓存·架构
需要8262 小时前
缓存与数据库一致性:延迟双删与订阅 binlog 的取舍
数据库·缓存
眼不痛请看我3 小时前
Ubuntu_22.04_LTS虚拟机安装指南
linux·数据库·ubuntu