4. 故障转移流程详解:哨兵检测、主观下线、客观下线、Leader选举、从节点晋升
Redis Sentinel(哨兵)是 Redis 高可用架构的核心组件。当主节点发生故障时,哨兵集群通过一套严谨的分布式共识流程完成故障转移。整个流程分为五个关键阶段:哨兵检测、主观下线、客观下线、Leader 选举、从节点晋升。下面逐一拆解每个阶段的原理与实现细节。
4.1 哨兵检测:心跳与信息交换
每个哨兵节点以每秒一次的频率向所有已知的 Redis 实例(主节点、从节点、其他哨兵)发送 PING 命令,用于检测实例的存活状态。哨兵之间通过 __sentinel__:hello 频道交换彼此对主节点状态的认知。
关键参数:
down-after-milliseconds:哨兵判定实例主观下线的超时时间,默认 30000ms。sentinel monitor <master-name> <ip> <port> <quorum>:定义监控的主节点及客观下线所需的投票数。
4.2 主观下线(Subjectively Down, SDOWN)
当单个哨兵节点在 down-after-milliseconds 时间内未收到主节点的有效 PONG 回复(或回复超时),该哨兵会将该主节点标记为主观下线。此状态仅代表该哨兵自身的判断,不涉及集群共识。
| 状态 | 触发条件 | 影响范围 |
|---|---|---|
| SDOWN | 单个哨兵 PING 超时 | 仅该哨兵本地标记 |
| ODOWN | 达到 quorum 数量的哨兵确认 SDOWN | 整个哨兵集群共识 |
4.3 客观下线(Objectively Down, ODOWN)
当某个哨兵将主节点标记为 SDOWN 后,它会通过 SENTINEL is-master-down-by-addr 命令向其他哨兵发起投票询问,请求其他哨兵确认该主节点是否也处于 SDOWN 状态。当收到至少 quorum 个(含自身)哨兵确认后,该哨兵将主节点状态升级为客观下线,并触发故障转移流程。
quorum 设置建议: 对于 3 个哨兵的集群,quorum 通常设为 2;对于 5 个哨兵,quorum 设为 3。quorum 必须大于哨兵总数的一半,才能避免脑裂。
4.4 Leader 选举:Raft 风格的共识
一旦主节点被标记为 ODOWN,哨兵集群需要选举出一个 Leader 来负责执行实际的故障转移操作。选举过程基于 Raft 算法 的简化实现:
- 发起选举: 每个检测到 ODOWN 的哨兵都会将自己设置为候选人,并向其他哨兵发送投票请求(包含当前纪元
epoch)。 - 投票规则: 每个哨兵在每个纪元内只能投一票,遵循先到先得原则。哨兵会优先投票给请求中纪元最大的候选人。
- 选举获胜: 获得超过半数哨兵投票(即
majority,至少N/2 + 1)的候选人成为 Leader。如果平票,则随机等待后进入下一轮选举。 - Leader 确认: 当选的 Leader 会获得一个唯一的
config-epoch,后续所有配置变更都以此纪元为准。
4.5 从节点晋升:Leader 执行故障转移
当选的 Leader 负责执行具体的故障转移操作,步骤如下:
- 筛选从节点: Leader 从所有从节点中排除以下节点:
- 处于 SDOWN 或 ODOWN 状态的从节点。
- 最近一次与主节点通信时间超过
down-after-milliseconds的从节点。 - 优先级(
slave-priority)为 0 的从节点(表示永不晋升)。
- 排序与选择: 对剩余从节点按以下优先级排序:
- 优先级(
slave-priority)值越小越优先。 - 复制偏移量(replication offset)越大越优先,表示数据越新。
- 运行 ID(run ID)字典序越小越优先。
- 优先级(
- 晋升操作: Leader 向选中的从节点发送
SLAVEOF NO ONE命令,使其断开与旧主节点的复制关系,成为新的主节点。 - 配置更新: Leader 将新主节点的信息广播给所有哨兵,并更新
config-epoch。其他从节点通过SLAVEOF命令切换复制目标到新主节点。
注意: 如果原主节点在故障转移后恢复上线,哨兵会检测到它已成为一个从节点(因为其
runid 与当前主节点不一致),并自动将其配置为当前新主节点的从节点,避免出现双主脑裂。
4.6 故障转移时序与关键参数
| 阶段 | 耗时估算 | 关键配置 | 说明 |
|---|---|---|---|
| 哨兵检测 | 持续进行 | sentinel monitor |
每秒 PING 一次 |
| 主观下线 | down-after-milliseconds | down-after-milliseconds |
默认 30s |
| 客观下线 | 毫秒级(网络延迟) | quorum |
投票确认 |
| Leader 选举 | 毫秒~秒级 | failover-timeout |
Raft 选举 |
| 从节点晋升 | 毫秒级 | slave-priority |
执行 SLAVEOF NO ONE |
4.7 故障转移后的数据一致性保证
故障转移过程中,可能存在部分数据未同步到新主节点的情况。Redis 哨兵采用异步复制,因此无法保证强一致性。但在大多数场景下,通过以下机制保证最终一致性:
- 复制偏移量优先: 选择数据最完整的从节点晋升,最大限度减少数据丢失。
- 客户端重定向: 故障转移后,哨兵通过
switch-master事件通知客户端,客户端重新连接新主节点。 - 原主节点降级: 原主节点恢复后自动成为从节点,从新主节点同步数据,补全丢失的写入。
生产建议: 对于需要更高数据安全性的场景,可以启用
min-slaves-to-write 和 min-slaves-max-lag 参数,限制主节点在从节点数量不足或复制延迟过大时拒绝写入,减少故障转移时的数据丢失风险。