Redis 哨兵模式如何实现故障自动切换

Redis 哨兵模式是 Redis 高可用架构中的核心组件,也是面试中高频出现的话题。很多候选人对哨兵模式的理解停留在“监控、通知、自动故障转移”这几个关键词上,但真正追问“故障切换的具体流程是什么”“主观下线与客观下线的区别”“选举 Leader 哨兵的细节”时,往往答不上来。本文将从面试实战角度出发,系统拆解 Redis 哨兵模式的故障自动切换机制。

一、哨兵模式的基本架构

在理解故障切换之前,先要厘清哨兵模式的基本组成:

  • 哨兵节点(Sentinel):独立运行的进程,通常部署奇数个(至少 3 个),负责监控、判断、选举和通知。
  • 主节点(Master):处理写请求,是哨兵监控的核心对象。
  • 从节点(Slave/Replica):复制主节点数据,作为故障时的备选。
  • 数据节点与哨兵节点的关系:哨兵不存储数据,只负责管理。哨兵之间通过 __sentinel__:hello 频道互相发现和通信。

一个典型的部署是:1 个 Master + 2 个 Slave + 3 个 Sentinel。哨兵节点可以和数据节点部署在同一台机器,但生产环境建议分开,避免机器故障导致判断失真。

二、故障发现:主观下线与客观下线

故障切换的第一步是“发现故障”。这里有两个关键概念,也是面试中极易混淆的点。

1. 主观下线(Subjectively Down,SDOWN)

每个哨兵节点会以每秒一次的频率向所有被监控节点(Master、Slave、其他 Sentinel)发送 PING 命令。如果在 down-after-milliseconds(默认 30 秒)内没有收到有效回复,该哨兵就会将该节点标记为“主观下线”。

注意:主观下线是单个哨兵的“一家之言”,可能是网络抖动导致的误判,不能直接触发故障切换。

2. 客观下线(Objectively Down,ODOWN)

当某个哨兵判定 Master 主观下线后,它会通过 SENTINEL is-master-down-by-addr 命令向其他哨兵询问:“你们也认为这个 Master 挂了吗?”

如果收到足够数量(达到 quorum 法定票数)的哨兵回复“是”,则该 Master 被标记为“客观下线”。此时才真正进入故障切换流程。

quorum 的配置:在 sentinel monitor mymaster ip port quorum 中设置。例如 3 个哨兵,quorum 设为 2,表示至少 2 个哨兵认为 Master 挂了才判定客观下线。quorum 只用于判定下线,不用于选举 Leader。

这里有一个面试常问的细节:客观下线是“针对 Master 节点”的概念,Slave 和 Sentinel 只有主观下线,没有客观下线。 因为从节点挂掉不需要自动切换,影响较小。

三、Leader 哨兵选举

判定 Master 客观下线后,多个哨兵都可能想执行故障切换。但同一时刻只能有一个哨兵作为“执行者”,这个执行者称为 Leader Sentinel。选举过程基于 Raft 算法的思想:

  1. 发起选举:任何一个判定客观下线的哨兵都可以发起选举,向其他哨兵发送 SENTINEL is-master-down-by-addr 命令,并将自己的 runid 作为“我想当 Leader”的请求。
  2. 投票规则:每个哨兵在一个选举周期(epoch)内只有一票,先到先得。收到请求的哨兵如果还没投票,就投给第一个请求者,并返回自己的投票结果。
  3. 当选条件:候选哨兵需要获得超过半数的票数(注意:是超过半数,不是 quorum),且票数不少于 quorum。例如 3 个哨兵,需要 2 票;5 个哨兵,需要 3 票。
  4. 选举失败重试:如果一轮选举没有选出 Leader,会等待一个随机时间后重新发起,避免活锁。

关键点:Leader 选举需要半数以上哨兵参与投票,因此哨兵数量必须是奇数,且至少 3 个。如果只有 2 个哨兵,挂掉一个就无法选举,故障切换失效。

四、新 Master 的挑选

Leader Sentinel 选出后,它负责从剩余的 Slave 中挑选一个升级为新的 Master。挑选规则按优先级依次比较:

  1. 排除不健康的 Slave:主观下线、断线时间过长、与 Master 断开超过 down-after-milliseconds * 10 的从节点直接淘汰。
  2. 优先级(replica-priority):值越小优先级越高。默认 100,设为 0 表示永不参与选举。
  3. 复制偏移量(offset):优先级相同时,选择复制偏移量最大(数据最新)的 Slave。
  4. runid 字典序:前两项都相同时,选择 runid 最小的节点,保证结果确定。

选出新 Master 后,Leader Sentinel 会向其发送 SLAVEOF NO ONE 命令,使其成为 Master。

五、故障切换的完整流程

综合以上步骤,一次完整的故障切换流程如下:

  1. 持续监控:每个 Sentinel 每秒 PING 所有节点。
  2. 主观下线:某 Sentinel 发现 Master 超时未响应,标记 SDOWN。
  3. 客观下线:该 Sentinel 向其他 Sentinel 确认,达到 quorum 后标记 ODOWN。
  4. Leader 选举:发起 Raft 选举,选出 Leader Sentinel。
  5. 挑选新 Master:按优先级、offset、runid 规则选出最佳 Slave。
  6. 提升新 Master:向选中的 Slave 发送 SLAVEOF NO ONE
  7. 重配置其他 Slave:向其余 Slave 发送 SLAVEOF new-master,让它们复制新 Master。
  8. 通知客户端:通过发布订阅机制,客户端可订阅 +switch-master 事件感知切换。
  9. 旧 Master 恢复:如果旧 Master 重新上线,Sentinel 会将其降级为 Slave,复制新 Master。

六、面试高频追问与易错点

1. quorum 和 majority 的区别?
quorum 用于判定客观下线,majority 用于 Leader 选举。两者不能混淆。例如 5 个哨兵,quorum=2,majority=3。可能出现判定下线但选不出 Leader 的情况。

2. 哨兵模式会丢数据吗?
会。Redis 的复制是异步的,Master 故障时可能有一部分写数据还没同步到 Slave,切换后这部分数据丢失。这是哨兵模式的固有缺陷,也是面试常考的“Redis 高可用不等于强一致”。

3. 脑裂问题怎么解决?
原 Master 因网络分区被误判下线,切换后新 Master 产生,此时原 Master 恢复,出现两个 Master。可通过 min-replicas-to-writemin-replicas-max-lag 配置,要求至少 N 个 Slave 确认才允许写入,降低脑裂丢数据风险。

4. 哨兵能保证强一致性吗?
不能。哨兵只解决高可用,不解决一致性。需要强一致应使用 Redis Cluster 或配合业务层方案。

5. 为什么哨兵至少 3 个?
因为 Leader 选举需要超过半数投票,2 个哨兵挂一个就无法达到多数,无法完成故障切换。

七、总结

Redis 哨兵模式的故障自动切换,核心可概括为“发现—选举—切换—通知”四步:通过主观下线和客观下线发现故障,通过 Raft 选举产生 Leader 哨兵,由 Leader 挑选最优 Slave 提升为 Master,最后重配置集群并通知客户端。理解 quorum 与 majority 的区别、SDOWN 与 ODOWN 的差异、新 Master 的挑选规则,是回答这类面试题的关键。掌握这些细节,不仅能应对面试,也能在生产环境中正确配置和排查哨兵集群问题。

未经允许不得转载:任鹏个人博客 » Redis 哨兵模式如何实现故障自动切换

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏