# 18. Redis 哨兵模式如何保障高可用性,如何处理故障切换?
# 标准答案
Redis 哨兵(Sentinel)模式是 Redis 提供的高可用性(HA)方案,用于监控 Redis 主从集群的状态,自动完成主节点故障检测、从节点选举以及主从切换,确保 Redis 服务的连续可用性。其核心机制包括:主节点监控(Monitoring)、自动故障转移(Failover)、通知机制(Notification)。故障切换流程由多个 Sentinel 节点投票选出新的主节点,并更新配置,保障服务不中断。
# 1️⃣ Redis 哨兵模式的核心机制
Redis 哨兵模式的目标是在主节点故障时,能自动选举新的主节点,并完成主从切换,同时通知客户端更新主节点信息。它的核心工作包括:
# (1)主节点监控(Monitoring)
- 每个 Sentinel 进程会定期(默认每秒钟)向所有 Redis 节点(主从)发送
PING
命令,检查其状态。 - 如果 主节点 在
down-after-milliseconds
(默认 30 秒)内连续未响应,Sentinel 认为其主观下线(Subjectively Down, SDOWN)。 - 只有当多个 Sentinel 协商一致 后,才会认定主节点客观下线(Objectively Down, ODOWN),触发故障转移。
# (2)自动故障转移(Failover)
当 Sentinel 确认主节点 ODOWN 后,执行以下步骤进行故障切换:
选举新的主节点(Leader Election):
- 多个 Sentinel 通过 Raft 算法进行领导者选举,只有被过半数 Sentinel 认可的 Sentinel 才能执行故障切换。
从节点晋升为新主节点:
- 被选中的 Sentinel 发送
SLAVEOF NO ONE
命令,使某个从节点成为新的主节点。 - 该 Sentinel 还会要求其他从节点重新复制新主节点,防止脑裂。
- 被选中的 Sentinel 发送
通知客户端更新主节点地址:
- Sentinel 会向客户端发布
+switch-master
消息,告知新主节点的 IP 和端口,使客户端更新连接信息。
- Sentinel 会向客户端发布
原主节点恢复后的处理:
- 若旧的主节点重新上线,它会被 Sentinel 重新标记为从节点,加入复制集群。
# (3)通知机制(Notification)
- Sentinel 通过 Pub/Sub 机制,通知 Redis 服务器和其他服务(如应用层)主从切换情况。
- 客户端可订阅 Sentinel,获取实时的主从变更信息,以便更新 Redis 连接。
# 2️⃣ Redis 故障切换的详细流程
以下是 Redis 哨兵处理主节点故障的完整步骤:
sequenceDiagram
participant Client
participant Sentinel1
participant Sentinel2
participant Sentinel3
participant Master
participant Slave1
participant Slave2
Master->>Sentinel1: PING
Master->>Sentinel2: PING
Master->>Sentinel3: PING
Sentinel1-->>Sentinel2: Master 没有响应
Sentinel2-->>Sentinel3: Master 没有响应
Sentinel1->>Sentinel2: 确认 ODOWN 状态
Sentinel2->>Sentinel3: 确认 ODOWN 状态
Sentinel1->>Sentinel3: 选举 Leader
Sentinel2->>Sentinel1: 选举 Leader
Sentinel1->>Sentinel2: 选举成功,Sentinel1 成为 Leader
Sentinel1->>Slave1: 发送 SLAVEOF NO ONE
Slave1->>Sentinel1: 变更为新主节点
Sentinel1->>Slave2: 发送 SLAVEOF 新主节点
Slave2->>Sentinel1: 变更为从节点
Sentinel1->>Client: 发送 +switch-master 事件
Client->>Sentinel1: 更新 Redis 连接
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 3️⃣ Redis Sentinel 如何保障数据一致性?
# (1)最少从节点可用机制(min-slaves-to-write)
在主节点进行写操作时,Sentinel 可以配置 min-slaves-to-write
和 min-slaves-max-lag
选项,以确保至少有一定数量的从节点同步到最新数据。
- 示例配置:这个配置表示:
min-slaves-to-write 2 min-slaves-max-lag 10
1
2- 至少 2 个从节点 需要处于可用状态,主节点才能继续处理写操作。
- 如果从节点的复制延迟超过 10 秒,它将不计入可用从节点。
- 这可以防止主节点挂掉时,所有从节点都滞后,导致数据丢失。
# (2)避免脑裂(Split-Brain)
Redis Sentinel 通过以下方式防止脑裂(即同时有两个 Redis 认为自己是主节点):
- 多 Sentinel 选举机制:只有获得多数 Sentinel 认可的新主节点才会被客户端接受。
- 原主节点恢复后自动降级为从节点,避免两个主节点并存。
- 使用
quorum
(法定人数)参数,确保至少一半以上 Sentinel 参与决策。
例如:
sentinel monitor mymaster 192.168.1.100 6379 3
其中 3
代表至少需要 3 个 Sentinel 认定主节点故障,才会触发故障切换。
# 4️⃣ Sentinel 模式的缺陷与优化方案
# (1)哨兵自身的单点故障
- Sentinel 本身也是一个分布式系统,如果 Sentinel 数量太少,可能会导致误判或者选举失败。
- 优化方案:
- 部署至少 3 个 Sentinel,确保投票正常进行。
- 监控 Sentinel 进程,确保其不被意外杀死。
# (2)主从数据复制延迟
- 在主节点故障时,某些数据可能尚未复制到从节点,导致切换后数据丢失。
- 优化方案:
- 结合
WAIT
命令,确保数据写入多个从节点后再返回成功。 - 采用
min-slaves-to-write
确保数据安全性。
- 结合
# (3)客户端连接更新问题
- 哨兵不会主动断开客户端连接,客户端需要手动更新 Redis 连接。
- 优化方案:
- 使用 Redis 提供的
sentinel get-master-addr-by-name
命令自动发现主节点地址。 - 采用支持 Sentinel 的 Redis 客户端,如 Jedis、Lettuce。
- 使用 Redis 提供的
# 深入追问
🔹 Sentinel 和 Redis Cluster 有何区别?何时选用哪种方案?
🔹 在高并发写入场景下,如何确保故障切换时数据不会丢失?
🔹 Sentinel 选举新主节点时,如果所有从节点都滞后 10 秒,怎么办?
🔹 如何监控 Sentinel 进程,确保其不被异常终止?
# 相关面试题
🔹 Redis Sentinel 如何处理脑裂问题?
🔹 如何配置 Redis Sentinel,确保主节点故障后能快速切换?
🔹 Redis Sentinel 和 ZooKeeper 哪种更适合分布式协调?
🔹 如何在 Sentinel 模式下保证主从数据的强一致性?