Redis的主从复制解决了数据冗余和读扩展的问题,但它有一个明显的短板:当主节点发生故障时,从节点不会自动升级为主节点,整个集群的写能力就中断了。如果不做任何处理,运维人员只能半夜爬起来手动执行SLAVEOF NO ONE命令切换主从,再逐个通知客户端修改连接地址。Redis Sentinel哨兵模式就是官方为这个场景提供的解决方案,它能够自动完成故障检测、主从切换和配置通知,是目前中小规模Redis部署中最常用的高可用架构。

一、Sentinel的核心工作机制
哨兵本身是一个独立的进程,不存储业务数据,只负责监控工作。一个健壮的哨兵部署至少需要三个哨兵实例,且建议分布在不同的物理机或虚拟机上。为什么必须是奇数个?这和领导者选举的投票机制有关,偶数个哨兵在网络分区时容易出现平票,导致选举失败、故障转移迟迟无法进行。
哨兵的工作流程可以概括为四个步骤:监控、通知、自动故障转移、配置中心。监控指哨兵定期向主从节点和其他哨兵发送命令探测存活状态;通知指节点出现异常时,哨兵可以通过API通知系统管理员或下游程序;自动故障转移是核心能力,当主节点不可用时,哨兵会挑选一个最优从节点提升为新主,并让其他从节点改为复制新主;配置中心则是指客户端可以连接哨兵查询当前主节点地址,主从切换后客户端能自动感知新地址。
在探测方式上,每个哨兵每秒向所有已知节点发送PING命令,如果某个节点在down-after-milliseconds时间内没有回复有效响应,该哨兵就会将其标记为主观下线(SDOWN)。注意这里的用词,主观下线只是单个哨兵的看法,可能是网络抖动导致的误判,此时还不会触发故障转移。
二、主观下线、客观下线与领导者选举
单个哨兵认为主节点下线后,它会询问其他哨兵:你们也觉得这个主节点挂了吗?当超过指定数量(quorum参数)的哨兵都认为主节点下线时,主节点才被标记为客观下线(ODOWN)。这个设计很聪明地避免了网络分区带来的误判:假设某个哨兵和主节点之间网络断了,但主节点本身是正常的,此时只有这一个哨兵认为它下线,其他哨兵的探测都正常,客观下线条件不满足,自然不会发生错误的切换。
确认客观下线后,哨兵之间需要选出一个领导者来执行故障转移。选举采用Raft算法的思想:每个发现主节点客观下线的哨兵都会向其他哨兵发送拉票请求,希望成为领导者。每个哨兵在每轮选举中只能投一票,且遵循先到先得的原则。得到超过半数哨兵投票(majority,注意是配置了确认投票的哨兵总数的一半以上,而不是quorum)的候选者成为领导者。这也是要求哨兵数量为奇数的原因,三节点部署时最多容忍一个哨兵故障,五节点部署时最多容忍两个。
quorum和majority是两个容易混淆的参数。quorum只影响客观下线的判定,也就是故障检测的敏感度;而领导者选举和后续执行故障转移的授权,需要的是majority。举个例子:五个哨兵,quorum配置为2,那么两个哨兵认为主节点下线就构成客观下线,但要想成功选出领导者执行切换,仍然需要至少三个哨兵在线参与投票。
三、部署配置实战
下面给出一个最小化的哨兵配置文件。假设主节点IP为192.168.0.11,端口6379,部署两个从节点192.168.0.12和192.168.0.13,哨兵分别部署在这三台机器上。
# sentinel.conf 配置文件 port 26379 # 监控名为 mymaster 的主节点,quorum 设置为 2 sentinel monitor mymaster 192.168.0.11 6379 2 # 主节点超过 5 秒无响应则判定为主观下线 sentinel down-after-milliseconds mymaster 5000 # 故障转移超时时间,默认 3 分钟 sentinel failover-timeout mymaster 180000 # 同时只允许一个从节点向新主同步数据 sentinel parallel-syncs mymaster 1 # 哨兵自身密码(可选,建议生产环境开启) # requirepass yourpassword # 连接主从节点时使用的密码(如果 Redis 设置了 requirepass) # sentinel auth-pass mymaster yourpassword
启动方式很简单,使用redis-sentinel命令指定配置文件即可:
# 启动哨兵 redis-sentinel /etc/redis/sentinel.conf # 或者用 redis-server 以 sentinel 模式启动 redis-server /etc/redis/sentinel.conf --sentinel
几个参数需要特别留意。down-after-milliseconds不宜设置得太小,网络偶尔抖动几秒很正常,设成几百毫秒会导致频繁误判切换;parallel-syncs控制故障转移后有多少从节点可以同时向新主发起全量复制,设得越大切换后数据同步越快,但同步期间这些从节点不可用,一般设为1比较稳妥。
验证哨兵工作是否正常,可以使用redis-cli连接哨兵端口执行命令:
# 查看主节点信息 redis-cli -p 26379 sentinel get-master-addr-by-name mymaster # 查看哨兵整体状态 redis-cli -p 26379 sentinel master mymaster # 手动触发一次故障转移(测试用) redis-cli -p 26379 sentinel failover mymaster
四、客户端如何接入哨兵
客户端不应该硬编码主节点地址,而应该连接哨兵集群查询主节点位置。以Java的Jedis为例,接入方式如下:
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
public class SentinelDemo {
public static void main(String[] args) {
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.0.11:26379");
sentinels.add("192.168.0.12:26379");
sentinels.add("192.168.0.13:26379");
// 参数依次为:master 名称、哨兵集合、连接池配置、密码
JedisSentinelPool pool = new JedisSentinelPool(
"mymaster", sentinels, null, null);
try (var jedis = pool.getResource()) {
jedis.set("demo:key", "hello sentinel");
System.out.println(jedis.get("demo:key"));
}
pool.close();
}
}
客户端内部的工作原理是:初始化时连接任意一个哨兵,通过SENTINEL get-master-addr-by-name命令获取主节点地址并建立连接;同时订阅哨兵的+switch-master频道,一旦发生主从切换,客户端收到通知后会自动断开旧连接,重新解析新主地址。整个过程对业务代码透明,写操作在切换完成后的几秒内即可恢复。
使用Spring Boot的话,配置更加简洁,只需在application.yml中声明哨兵地址和master名称即可,Spring Data Redis会自动处理连接切换,这里不再展开。
五、部署中的常见坑点
第一,哨兵数量不足三个。有些测试环境只部署一个哨兵,单哨兵无法构成可靠的故障判断,网络一抖动就切换,且无法容忍自身故障。生产环境至少三个,跨机架或跨可用区分布。
第二,主从节点都设置了requirepass但哨兵没配密码,或者主从密码不一致。哨兵连接不上节点时会一直报错,故障转移也无法执行。如果主从密码不同,需要用sentinel auth-user和sentinel auth-pass分别为不同节点指定凭据。
第三,客户端使用只读连接从不更新。一些自研客户端没有订阅switch-master事件,切换后仍连旧主,旧主降级为从节点后写入会直接报错。选型时务必确认客户端库支持哨兵模式,如Jedis、Lettuce、redis-py等都原生支持。
第四,故障转移期间存在数据丢失窗口。主从复制是异步的,主节点宕机时未同步到从节点的数据会永久丢失。哨兵保证的是可用性而不是零丢失,如果业务对数据一致性要求极高,需要配合min-replicas-to-write参数限制写入条件,或者在应用层做补偿,但这样做会牺牲部分可用性,需要根据业务权衡。
整体来看,Sentinel适合数据量不大、写入压力中等、希望以较低成本获得高可用能力的场景。如果数据量超过单机内存或者需要在线水平扩容,就应该考虑Redis Cluster集群方案了。理解哨兵的判定和选举机制,能帮助你在故障发生时快速定位问题,而不是盲目重启服务。
Redis Sentinel哨兵模式自动故障转移修改时间:2026-09-03 12:11:01