Redis的主从复制解决了读扩展和数据冗余的问题,但它有一个明显的短板:一旦master节点宕机,需要人工介入把某个slave切换成新的master,这个过程中服务可能中断几分钟甚至更久。生产环境显然不能接受这种恢复速度,而Redis Sentinel(哨兵)就是官方提供的高可用解决方案。哨兵本身是独立运行的进程,负责监控Redis节点、判断故障、执行自动切换,并在切换完成后通知客户端。下面我们从原理到实操,完整讲清楚哨兵的部署和使用。

哨兵的核心工作机制:从主观下线到自动切换
理解哨兵的工作方式,关键是抓住两个概念:主观下线(SDOWN)和客观下线(ODOWN)。每个哨兵节点会以每秒一次的频率向master、slave以及其他哨兵发送PING命令,如果在down-after-milliseconds配置的时间内没有收到有效回复,该哨兵就会单方面认为这个节点主观下线。注意这只是单个哨兵的判断,网络抖动、哨兵自身负载过高都可能造成误判,所以哨兵引入了客观下线机制。
当某个哨兵认为master主观下线后,它会询问其他哨兵:你们觉得master挂了吗?如果同意的哨兵数量达到配置文件中quorum设定的值,master就被判定为客观下线。接下来哨兵之间会通过Raft协议选举出一个leader哨兵,由它来执行具体的故障转移操作。整个投票过程基于先到先得的原则,通常一轮就能选出leader,耗时在秒级。
leader哨兵执行故障转移时主要做三件事:第一,从存活的slave中挑选一个最优节点提升为master,挑选依据包括slave优先级(slave-priority)、复制偏移量大小、runid大小等;第二,让其余slave改为复制新的master;第三,通过发布订阅机制通知客户端新的master地址。旧master恢复上线后,会被降级为slave去复制新master。值得一提的是,quorum只影响客观下线的判定,真正执行故障转移需要majority授权,这也是为什么哨兵通常部署奇数个节点且至少3个。
一主二从三哨兵的完整部署实践
推荐的生产部署方案是至少3个哨兵节点,配合一主二从的Redis实例。假设三台服务器IP分别为192.168.1.11、192.168.1.12、192.168.1.13,首先在三台机器上配置主从关系。在12和13两台机器上编辑redis.conf,添加主从配置:
# 192.168.1.12 和 192.168.1.13 上执行,配置为 11 的从节点 # Redis 5.0 之前使用 slaveof,之后推荐使用 replicaof replicaof 192.168.1.11 6379 # 从节点默认只读,保持默认即可 replica-read-only yes # 建议设置主从认证密码,保证数据传输安全 masterauth YourStrongPassword requirepass YourStrongPassword
主从配置完成后,在三台机器上分别创建哨兵配置文件sentinel.conf。哨兵配置的核心参数如下:
# 哨兵监控的 master 名称为 mymaster,后面是 master 地址和 quorum 值 # quorum 设为 2 表示至少 2 个哨兵同意才判定客观下线 sentinel monitor mymaster 192.168.1.11 6379 2 # 30 秒无响应判定为主观下线,网络不稳定时可适当调大 sentinel down-after-milliseconds mymaster 30000 # 故障转移超时时间,超时后哨兵会重新尝试 sentinel failover-timeout mymaster 180000 # 同时只允许 1 个从节点进行同步,避免 master 压力过大 sentinel parallel-syncs mymaster 1 # 如果 Redis 设置了密码,哨兵也需要配置认证 sentinel auth-pass mymaster YourStrongPassword
配置文件准备好后,在每台机器上启动哨兵进程。注意哨兵进程要以独立方式运行,不要和Redis实例混在同一个配置里:
# 启动哨兵,注意必须指定 sentinel 模式 redis-server /etc/redis/sentinel.conf --sentinel # 或者直接使用 sentinel 专用启动命令 redis-sentinel /etc/redis/sentinel.conf # 查看哨兵状态,确认 master 信息 redis-cli -p 26379 sentinel master mymaster # 查看已知从节点列表 redis-cli -p 26379 sentinel slaves mymaster
启动完成后可以通过sentinel get-master-addr-by-name mymaster命令验证哨兵是否正确识别了master地址。有一个容易忽略的细节:哨兵运行过程中会把自动发现的slave和其他哨兵的信息写回sentinel.conf文件,所以该文件必须保证哨兵进程有写权限,否则故障转移会失败。
验证故障转移与客户端接入方式
部署完成后必须做一次真实的故障演练。直接kill掉192.168.1.11上的Redis进程,然后观察哨兵日志。正常流程是:约30秒后哨兵判定客观下线,几秒内选出leader哨兵执行切换,日志中会出现+sdown、+odown、+switch-master等关键事件。切换完成后,用sentinel get-master-addr-by-name mymaster查询,返回的应该是新的master地址,比如192.168.1.12。再重启旧master的Redis进程,它会自动变成slave加入集群。
# 杀掉 master 进程模拟宕机 kill $(cat /var/run/redis_6379.pid) # 观察哨兵日志中的切换过程 tail -f /var/log/redis/sentinel.log # 验证新 master 已可写入 redis-cli -h 192.168.1.12 -a YourStrongPassword set test:key hello
客户端接入方面,强烈建议不要在应用里写死master地址,而是通过哨兵获取。以Java的Jedis为例,接入时指定哨兵地址集合和master名称即可,连接池会自动感知主备切换:
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.11:26379");
sentinels.add("192.168.1.12:26379");
sentinels.add("192.168.1.13:26379");
// 哨兵会自动返回当前 master 的地址
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, "YourStrongPassword");
try (Jedis jedis = pool.getResource()) {
jedis.set("test:key", "hello");
}使用Spring Boot时,在配置文件中同样只需配置sentinel节点列表和master名称,框架会处理好故障转移后的连接切换。这里有一个常见的坑需要提醒:如果客户端使用了连接池但池化配置不当,主备切换后可能出现大量连接超时,建议开启连接有效性检测并设置合理的testWhileIdle参数。
生产环境部署的注意事项总结
哨兵数量建议为奇数(3或5个),并且尽量和Redis实例分开部署在不同机器上。如果哨兵和Redis混部在同一台机器,机器整体宕机时会同时损失一个Redis节点和一个哨兵,极端情况下可能凑不够majority导致无法切换。quorum值的设置也要讲究:设为2是三节点的常见选择,既能容忍单哨兵故障,又能避免误判。
数据安全方面务必理解哨兵的局限:哨兵保证的是可用性而不是数据零丢失。异步复制意味着master宕机时,尚未同步到slave的最新写入可能丢失。如果业务对数据一致性要求高,可以在客户端开启WAIT命令或考虑使用Redis Cluster的更强保证。另外,down-after-milliseconds不要设置得太小,网络稍有抖动就触发切换,反而会造成频繁的主备来回切换,影响服务稳定性。
最后是运维层面的建议:哨兵自身的日志要接入监控告警,重点关注+switch-master事件,它意味着发生了一次线上故障转移,需要人工确认业务是否受影响;同时定期做故障演练,验证切换流程是否正常。把哨兵架构运维到位,一套简单的三机部署就能支撑绝大多数中等规模业务的Redis高可用需求。
Redis哨兵Redis Sentinel高可用修改时间:2026-09-03 12:39:08