# Redis 的哨兵机制是什么?
10 min read
Table of Contents
Redis 的哨兵机制是什么?
Redis 哨兵机制面试标准答案
【核心定义】
Redis Sentinel(哨兵)是 Redis 官方提供的一种高可用性(High Availability)解决方案,它是一个分布式系统,用于监控主从复制架构中的 Redis 实例,并在主节点发生故障时,自动完成故障检测、故障转移与配置更新,从而实现服务的持续可用。
【关键要点】
- 核心功能:监控(Monitoring)、自动故障转移(Automatic Failover)、配置提供者(Configuration Provider)。
- 部署模式:哨兵本身是一个独立的进程,通常以奇数个节点(如3或5个) 组成集群部署,通过 Raft 共识算法实现自身的高可用与决策。
- 监控对象:哨兵持续监控主节点(Master)及其下属的所有从节点(Slaves)的健康状态。
- 故障判定:采用主观下线(SDOWN) 和客观下线(ODOWN) 双重机制来判定主节点是否真正失效。
- 故障转移流程:当主节点被客观判定为下线后,哨兵集群会通过选举机制选出一个领导者哨兵(Leader Sentinel),由它负责执行具体的故障转移操作。
【深度推导/细节】
1. 故障检测的“双重保险”逻辑
-
主观下线(Subjectively Down, SDOWN):
- 定义:单个哨兵节点通过定期(如每秒一次)向主节点发送
PING命令,如果在配置的down-after-milliseconds时间内未收到有效回复(如PONG、LOADING、MASTERDOWN),则该哨兵主观地认为该主节点下线。 - 痛点:这仅是单个哨兵的“局部视图”,可能因网络抖动、自身负载过高而产生误判。
- 定义:单个哨兵节点通过定期(如每秒一次)向主节点发送
-
客观下线(Objectively Down, ODOWN):
- 定义:当某个哨兵主观判定主节点下线后,它会向其他哨兵节点发送
SENTINEL is-master-down-by-addr命令进行询问。当同意主节点下线的哨兵数量达到配置的法定人数(quorum) 时,主节点被标记为客观下线。 - 临界点
quorum:这是配置文件中的关键参数(如quorum 2)。它表示判断客观下线所需的最少哨兵票数,而非哨兵总数。设置quorum必须权衡灵敏性与误判风险。例如,3个哨兵时,quorum=2意味着需要至少2个哨兵同意。
- 定义:当某个哨兵主观判定主节点下线后,它会向其他哨兵节点发送
2. 领导者选举与故障转移的逐步拆解
一旦主节点被客观下线,故障转移流程启动:
- Step 1: 领导者哨兵选举:
- 所有监控该主节点的哨兵都有资格参选。
- 选举基于 Raft 算法 思想。最先检测到客观下线的哨兵会向其他哨兵发起投票请求。
- 每个哨兵在一个纪元(epoch) 内只能投一票,通常投给最先请求的哨兵。
- 获得超过半数(N/2 + 1) 选票的哨兵成为领导者。奇数个哨兵的部署正是为了能明确产生多数派,避免平局。
- Step 2: 筛选新主节点:
- 领导者哨兵从原主节点的从节点列表中,根据规则筛选出最适合晋升为新主节点的从节点。筛选规则优先级为:
- 网络连接状态良好。
- 优先级(
slave-priority配置)最高的。 - 复制偏移量(replication offset)最大的(即数据最完整的)。
- 运行ID(run id)字典序最小的。
- 领导者哨兵从原主节点的从节点列表中,根据规则筛选出最适合晋升为新主节点的从节点。筛选规则优先级为:
- Step 3: 提升新主与切换:
- 领导者哨兵向选中的从节点发送
SLAVEOF no one命令,使其升级为主节点。 - 然后,向其他所有从节点发送
SLAVEOF命令,指向新的主节点,重建复制关系。 - 最后,更新哨兵自身的配置,将监控对象改为新的主节点,并通知客户端(通过发布订阅更新配置)。
- 领导者哨兵向选中的从节点发送
3. 客户端集成与配置更新
- 哨兵作为配置提供者,客户端不再直连 Redis 主节点,而是连接哨兵集群。
- 客户端通过哨兵获取当前有效的主节点地址。当故障转移发生后,哨兵会通过 Redis 的发布订阅频道(
__sentinel__:hello) 广播新的主节点信息,智能客户端可以监听该频道并自动完成连接切换。
【关联/对比】
-
哨兵 vs 集群(Cluster):
- 哨兵:解决的是 高可用(HA) 问题,专注于主从故障转移。其架构仍是主从复制,写能力受限于单主节点,不具备数据分片(Sharding)能力。
- 集群:是 Redis 的分布式解决方案,同时实现了数据分片和高可用。它将数据自动分片到多个主节点上,每个主节点有对应的从节点,通过 Gossip 协议通信,故障转移在分片内部进行。
- 简单总结:需要线性扩展写性能和海量数据存储时用 Cluster;只需要保证主从高可用时用 Sentinel。
-
哨兵 vs 传统主从手动切换:
- 传统主从需要人工干预故障,恢复时间长。哨兵实现了全自动的故障转移,将服务中断时间(RTO)从分钟级降至秒级。
『面试官追问』
-
为什么哨兵节点推荐部署奇数个(如3个)?
- 核心是为了在领导者选举和客观下线投票中能够快速形成多数派(Majority),避免出现票数相等导致决策僵局。例如,3个节点允许1个节点故障,仍能形成2>1的多数派;4个节点也只能允许1个故障(因为需要3>2),但增加了网络开销和成本,容错能力并未提升。
-
quorum和选举领导者的“半数以上”是一回事吗?- 不是。这是两个不同的概念和阶段。
quorum是配置值,用于客观下线判定,指“认为主节点下线所需的最少哨兵同意数”。- “半数以上”(N/2 + 1)是领导者选举的硬性要求,由 Raft 算法保证,指“必须获得超过半数哨兵的投票才能当选”。例如,3个哨兵,
quorum可以设为2,但选举领导者必须获得至少2票。
-
故障转移期间数据会丢失吗?
- 有可能。Redis 主从复制是异步的。在主节点故障前,可能有一部分已确认写操作还未同步到从节点。这部分数据就会丢失。这是 Redis 在性能与一致性之间做的权衡。可以使用
redis.conf中的min-slaves-to-write和min-slaves-max-lag配置来降低丢失风险(要求主节点至少写入指定数量的、延迟小于指定值的从节点,否则拒绝写入)。
- 有可能。Redis 主从复制是异步的。在主节点故障前,可能有一部分已确认写操作还未同步到从节点。这部分数据就会丢失。这是 Redis 在性能与一致性之间做的权衡。可以使用
-
哨兵集群自己会脑裂吗?如何避免?
- 哨兵基于 Raft 算法,本身设计就是为了避免脑裂。在领导者选举阶段,一个纪元内只有一个领导者能获得多数票,这保证了决策的唯一性。在网络分区场景下,只有拥有多数哨兵的分区能选举出领导者并执行故障转移,少数分区因无法达到法定人数而不会行动,从而避免了“双主”出现。
-
客户端如何感知并连接到新的主节点?
- 智能客户端:客户端库(如 Jedis、Lettuce)集成了哨兵支持。启动时配置哨兵地址列表,客户端会从哨兵查询当前主节点地址,并订阅哨兵的频道以监听主节点切换事件,实现自动重定向。
- 代理层:可以通过 HAProxy、Keepalived 等代理,由哨兵脚本动态更新代理配置。