Redis 哨兵模式:原理、配置与故障排查全解析
文章目录
- [Redis 哨兵模式:原理、配置与故障排查全解析](#Redis 哨兵模式:原理、配置与故障排查全解析)
-
-
- 一、哨兵模式的核心定位(通俗理解)
- 二、哨兵模式的核心组件与架构
-
- [1. 核心组件](#1. 核心组件)
- [2. 典型架构](#2. 典型架构)
- [三、哨兵模式的核心工作流程(4 步)](#三、哨兵模式的核心工作流程(4 步))
-
- [1. 监控(持续检测)](#1. 监控(持续检测))
- [2. 故障转移(核心步骤)](#2. 故障转移(核心步骤))
- [3. 通知客户端](#3. 通知客户端)
- [4. 持续监控(故障恢复后)](#4. 持续监控(故障恢复后))
- 四、哨兵模式的核心配置(快速上手)
-
- [1. 哨兵配置文件(sentinel.conf)](#1. 哨兵配置文件(sentinel.conf))
- [2. 启动与验证](#2. 启动与验证)
- [3. 模拟故障转移(测试)](#3. 模拟故障转移(测试))
- 五、哨兵模式的核心特点
- [六、哨兵模式 vs Redis Cluster(核心区别)](#六、哨兵模式 vs Redis Cluster(核心区别))
- [七、哨兵模式常见问题排查(核心故障 + 原因 + 解决方案)](#七、哨兵模式常见问题排查(核心故障 + 原因 + 解决方案))
-
- 通用排查前置准备
- [1、核心问题 1:主节点宕机,哨兵无法触发故障转移(最常见)](#1、核心问题 1:主节点宕机,哨兵无法触发故障转移(最常见))
-
- 现象
- 核心原因(按排查优先级排序)
- [排查 & 解决步骤](#排查 & 解决步骤)
- [2、核心问题 2:哨兵误判主节点下线(假死),触发不必要的故障转移](#2、核心问题 2:哨兵误判主节点下线(假死),触发不必要的故障转移)
- [3、核心问题 3:故障转移完成后,从节点无法同步新主节点](#3、核心问题 3:故障转移完成后,从节点无法同步新主节点)
- [四、核心问题 4:哨兵节点自身无法加入集群,或与其他哨兵失联](#四、核心问题 4:哨兵节点自身无法加入集群,或与其他哨兵失联)
- 5、其他高频小问题
-
- [问题 1:主节点恢复后,自动成为新主节点的从节点,业务写入地址未更新](#问题 1:主节点恢复后,自动成为新主节点的从节点,业务写入地址未更新)
- [问题 2:哨兵执行故障转移时,出现「NOGOODSLAVE」错误(日志中可见)](#问题 2:哨兵执行故障转移时,出现「NOGOODSLAVE」错误(日志中可见))
- [问题 3:主从复制正常,但哨兵显示从节点数为 0](#问题 3:主从复制正常,但哨兵显示从节点数为 0)
- 6、哨兵模式生产环境避坑指南(预防问题比排查更重要)
- 总结
- 总结
-
Redis 哨兵模式(Redis Sentinel),是官方为解决 主从架构下主节点故障自动恢复 问题而设计的高可用方案 ------ 简单来说,哨兵模式就是给 Redis 主从集群配了一个 "智能监控管家",它能自动监控主从节点的健康状态,主节点宕机时自动把最优的从节点晋升为主节点,还能通知客户端更新连接地址,全程无需人工干预。
一、哨兵模式的核心定位(通俗理解)
主从复制解决了 "数据备份 + 读写分离",但有个致命问题:主节点宕机后,需要人工手动切换从节点为主节点,这会导致服务中断。
而哨兵模式就是主从架构的 "高可用补丁":
- 哨兵(Sentinel):独立的 Redis 进程(非业务节点),专门监控主从集群;
- 核心能力:监控→故障判定→自动故障转移→通知客户端,实现主节点故障的 "秒级自动恢复"。
二、哨兵模式的核心组件与架构
1. 核心组件
| 组件 | 作用 |
|---|---|
| 主节点(Master) | 处理写请求,是数据写入源(同主从复制) |
| 从节点(Replica) | 同步主节点数据,只读,主节点故障后可被晋升(同主从复制) |
| 哨兵节点(Sentinel) | 独立进程,至少部署 3 个(奇数),避免哨兵单点故障 |
2. 典型架构
plaintext
[哨兵节点1] ←→ [哨兵节点2] ←→ [哨兵节点3] (哨兵集群,通过投票机制判定故障)
↓ ↓ ↓
[主节点6379] ←→ [从节点6380] ←→ [从节点6381] (主从集群)
哨兵节点之间也会互相通信,同步节点状态,避免 "单个哨兵误判";
哨兵节点不存储业务数据,仅负责监控和故障转移,资源消耗极低。
Redis 哨兵模式架构拓扑图:
这个图表清晰展示哨兵节点、主节点、从节点的部署关系和通信方式,虽然看起来比较乱,但仔细看看还是比较简单的:
Redis Data Nodes
Sentinel Cluster
流言协议/状态同步
流言协议/状态同步
流言协议/状态同步
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
PING/监控
数据复制
数据复制
查询主节点地址/读写
查询主节点地址/读写
查询主节点地址/读写
业务操作
Sentinel 1
192.168.1.20:26379
Sentinel 2
192.168.1.21:26379
Sentinel 3
192.168.1.22:26379
Master
192.168.1.10:6379
读写
Slave 1
192.168.1.11:6379
只读/复制
Slave 2
192.168.1.12:6379
只读/复制
客户端
Client App
三、哨兵模式的核心工作流程(4 步)
1. 监控(持续检测)
每个哨兵节点会定期(默认 1 秒)向主节点、所有从节点、其他哨兵节点发送PING命令,检测节点是否存活:
若节点在down-after-milliseconds(默认 30 秒)内未回复PONG,哨兵将其标记为 "主观下线(SDOWN)"(单个哨兵的判断);
哨兵节点之间同步这个 "主观下线" 状态,若超过 quorum(配置的法定票数,如 3 个哨兵需 2 票) 的哨兵都判定该主节点下线,就标记为 "客观下线(ODOWN)"(集群共识,避免误判)。
2. 故障转移(核心步骤)
主节点被标记为 "客观下线" 后,哨兵集群会选举出一个 "领头哨兵",由它执行故障转移:
- 筛选可用从节点:排除宕机、同步延迟过高、网络不可达的从节点;
- 选举最优从节点:按 "优先级(replica-priority)> 复制偏移量(数据同步完整性)> 运行 ID(小的优先)" 排序,选出最优从节点;
- 晋升主节点 :领头哨兵向最优从节点发送
SLAVEOF NO ONE命令,使其晋升为新主节点; - 重定向其他从节点 :向剩余从节点发送
SLAVEOF 新主节点IP 端口命令,让它们同步新主节点的数据; - 标记旧主节点:将宕机的旧主节点标记为 "已下线",若其恢复上线,哨兵会让它成为新主节点的从节点。
Redis 哨兵故障转移流程图:
是
否
否
是
哨兵集群每秒PING主/从节点
主节点是否响应?
单个哨兵标记主节点「主观下线」
哨兵向集群询问主节点状态
超过半数哨兵确认主节点故障?
取消主观下线,继续监控
标记主节点「客观下线」
哨兵集群投票选举领头哨兵
领头哨兵筛选最优从节点
将最优从节点升级为新主节点
其余从节点切换到新主节点同步数据
通知客户端新主节点地址
原主节点恢复后作为从节点接入新主节点
3. 通知客户端
哨兵会通过 "发布订阅" 机制(频道+switch-master),将新主节点的地址通知给所有连接的客户端,客户端收到后自动更新连接地址,无需重启。
4. 持续监控(故障恢复后)
新主从集群建立后,哨兵继续监控所有节点,重复上述流程,保障高可用。
四、哨兵模式的核心配置(快速上手)
1. 哨兵配置文件(sentinel.conf)
conf
# 配置监控的主节点(格式:sentinel monitor 主节点名称 IP 端口 法定票数)
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点主观下线超时时间(毫秒)
sentinel down-after-milliseconds mymaster 30000
# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 180000
# 每次故障转移最多同步的从节点数(避免同时同步压垮新主节点)
sentinel parallel-syncs mymaster 1
# 若主节点有密码,需配置
# sentinel auth-pass mymaster 123456
2. 启动与验证
bash
# 1. 先启动主从节点(同主从复制)
redis-server redis-master.conf
redis-server redis-slave1.conf
redis-server redis-slave2.conf
# 2. 启动至少3个哨兵节点(修改端口避免冲突)
redis-sentinel sentinel1.conf # 默认端口26379
redis-sentinel sentinel2.conf # 端口26380
redis-sentinel sentinel3.conf # 端口26381
# 3. 查看哨兵状态(验证监控是否生效)
redis-cli -p 26379
127.0.0.1:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
mymaster:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
3. 模拟故障转移(测试)
bash
# 手动停止主节点(模拟宕机)
redis-cli -p 6379 SHUTDOWN
# 查看哨兵日志/状态,会发现:
# 1. 哨兵判定主节点客观下线;
# 2. 选举最优从节点(如6380)晋升为主节点;
# 3. 原从节点6381同步新主节点6380;
# 4. 哨兵状态中mymaster的address变为127.0.0.1:6380
# 恢复旧主节点(6379),它会自动成为新主节点(6380)的从节点
redis-server redis-master.conf
五、哨兵模式的核心特点
| 优点 | 缺点 |
|---|---|
| 自动故障转移,无需人工干预 | 仅解决高可用,未解决数据分片(所有节点存储全量数据,单机容量瓶颈) |
| 哨兵集群部署,无单点故障 | 故障转移有秒级中断(客户端需适配重连) |
| 轻量级,不影响业务节点性能 | 配置和运维比纯主从复杂(需管理哨兵集群) |
| 支持通知客户端,无缝切换 | 仅单主节点,写性能受限于单个节点 |
六、哨兵模式 vs Redis Cluster(核心区别)
这是新手最易混淆的点,用表格清晰对比:
| 维度 | 哨兵模式 | Redis Cluster |
|---|---|---|
| 核心目标 | 解决主从架构的高可用(自动故障转移) | 解决数据分片 + 高可用(分布式集群) |
| 数据存储 | 所有节点存储全量数据 | 哈希槽分片,每个主节点存储部分数据 |
| 写扩展 | 仅单主节点,无写扩展能力 | 多主节点,支持写性能水平扩展 |
| 故障转移 | 仅主节点故障转移 | 任意主节点故障都能自动转移,且不影响整体 |
| 适用场景 | 数据量小(GB 级)、读多写少、需高可用 | 数据量大(TB 级)、高并发读写、需水平扩展 |
七、哨兵模式常见问题排查(核心故障 + 原因 + 解决方案)
哨兵模式的核心故障集中在故障转移失败 、节点误判上下线 、从节点无法同步主节点 、哨兵集群无领头节点四类。
通用排查前置准备
排查前先获取核心状态信息,定位问题方向:
- 查看哨兵节点状态:
redis-cli -p 哨兵端口 INFO sentinel(确认监控的主节点状态、从节点数、哨兵数) - 查看主从复制状态:
redis-cli -p 主/从端口 INFO replication(确认主从角色、同步偏移量、连接状态) - 查看哨兵日志(关键):哨兵启动时指定日志文件,或通过
redis-cli -p 哨兵端口 CONFIG GET logfile获取日志路径,日志是排查所有问题的核心依据 - 检查节点网络:
ping 节点IP+telnet 节点IP 端口(确认主从、哨兵之间网络互通)
1、核心问题 1:主节点宕机,哨兵无法触发故障转移(最常见)
现象
主节点进程挂掉 / 网络中断,但哨兵始终未将从节点晋升为主节点,INFO sentinel中主节点状态仍为ok或down但无故障转移动作。
核心原因(按排查优先级排序)
- 未达到「客观下线」的法定票数(quorum)
- 哨兵集群无法选举出「领头哨兵」
- 所有从节点都不可用(宕机 / 同步延迟过高 / 优先级为 0)
- 哨兵配置错误(超时时间、密码、端口)
- 哨兵节点自身故障(进程挂掉、权限不足)
排查 & 解决步骤
(1) 检查主节点是否被标记为「客观下线(ODOWN)」:
执行redis-cli -p 哨兵端口 SENTINEL master 主节点名称,查看flags字段:
- 若为
S_DOWN(主观下线):说明只有部分哨兵判定主节点下线,未达到 quorum 法定票数; - 解决方案:确认哨兵集群正常运行的节点数≥quorum(如配置 quorum=2,需至少 2 个哨兵在线并判定主节点下线),重启故障的哨兵节点,确保哨兵之间网络互通。
(2) 检查哨兵是否能选举领头节点
故障转移的前提是哨兵集群选举出唯一的领头哨兵,选举失败则无法执行转移;
失败原因:哨兵节点数为偶数(脑裂风险)、哨兵之间网络不通、哨兵配置的master-name不一致;
解决方案:哨兵节点数必须部署奇数个(≥3) ,检查所有哨兵的master-name配置一致,确保哨兵之间 26379(默认)端口互通。
(3) 检查从节点可用性(哨兵筛选从节点的规则)
哨兵会过滤掉以下从节点,若全部被过滤则无法转移:
从节点状态为宕机:INFO replication中slave0的state非online;
从节点优先级为 0:redis-cli -p 从节点端口 CONFIG GET replica-priority返回 0(优先级 0 表示永不被晋升);
同步延迟过高:从节点的master_repl_offset(同步偏移量)与主节点差值过大,超过哨兵判定的有效范围;
从节点连接主节点时长过短:刚连接的从节点未完成全量同步,被哨兵判定为 "未就绪";
解决方案:重启故障从节点、将有效从节点的replica-priority改为 1-100(默认 100,值越小优先级越高)、等待从节点完成全量同步后再触发故障转移。
(4) 检查哨兵核心配置
确认down-after-milliseconds(主观下线超时)配置一致:所有哨兵对同一主节点的该配置必须相同,否则会出现判定不一致;
确认auth-pass配置正确:若主节点设置了密码,所有哨兵必须配置sentinel auth-pass 主节点名称 密码,否则哨兵无法连接主节点,无法判定状态;
确认parallel-syncs(故障转移后从节点同步新主节点的数量):若配置过大,可能导致新主节点被压垮,但不会直接导致转移失败。
2、核心问题 2:哨兵误判主节点下线(假死),触发不必要的故障转移
现象
主节点实际正常运行(能处理请求),但哨兵将其标记为下线并触发故障转移,导致主节点切换,业务出现短暂抖动。
核心原因
- 主节点压力过高,导致 PING 响应超时
- 主观下线超时时间(down-after-milliseconds)配置过小
- 主节点与哨兵之间网络抖动(丢包、延迟高)
- 主节点开启了保护模式,拒绝哨兵的 PING 请求
排查 & 解决步骤
(1) 调大主观下线超时时间
生产环境不建议将 down-after-milliseconds 设置小于 30000ms(30 秒),默认 30 秒是合理值,若网络环境较差,可调至 60000ms;
命令:redis-cli -p 哨兵端口 SENTINEL set 主节点名称 down-after-milliseconds 60000(所有哨兵需统一修改)。
(2) 排查主节点高负载原因
主节点 CPU / 内存 / 磁盘 IO 过高,会导致无法及时响应哨兵的 PING 命令;
排查:redis-cli -p 主节点端口 INFO stats(查看命令执行量)、top(查看 Redis 进程 CPU 占用)、iotop(查看磁盘 IO);
解决方案:优化慢查询(SLOWLOG get)、限制大 key 操作、扩容主节点资源、通过从节点分担读请求。
(3) 解决网络抖动问题
主节点与哨兵部署在不同机房 / 网段时,易出现网络丢包;
排查:ping 主节点IP -i 0.1(持续 ping,查看丢包率)、mtr 主节点IP(查看网络路由延迟);
解决方案:将哨兵与主从节点部署在同一网段,优化网络链路,避免跨公网部署哨兵。
(4) 关闭主节点的保护模式
若主节点开启了保护模式(protected-mode yes),且未配置绑定 IP,会拒绝哨兵的远程连接;
解决方案:redis-cli -p 主节点端口 CONFIG SET protected-mode no(生产环境建议配合bind配置指定哨兵 IP,更安全)。
3、核心问题 3:故障转移完成后,从节点无法同步新主节点
现象
哨兵将从节点 A 晋升为新主节点,但其他从节点无法同步新主节点 A,INFO replication中从节点的state为connecting或error。
核心原因
- 新主节点设置了密码,从节点未配置 masterauth
- 新主节点的 replica-read-only 配置被修改(非只读)
- 从节点与新主节点网络不通,或端口被防火墙拦截
- 新主节点的复制积压缓冲区满,导致从节点无法做部分复制,全量复制又失败
排查 & 解决步骤
(1) 检查新主节点密码与从节点 masterauth 配置
若新主节点有密码:redis-cli -p 新主节点端口 CONFIG GET requirepass;
从节点必须配置相同密码:redis-cli -p 从节点端口 CONFIG SET masterauth 密码,并持久化配置(CONFIG REWRITE)。
(2) 确认新主节点为只读模式(故障转移后自动设置,若被修改会出问题)
新主节点晋升后,哨兵会自动将其设为replica-read-only no(可写),但从节点必须保持replica-read-only yes;
检查从节点配置:redis-cli -p 从节点端口 CONFIG GET replica-read-only,确保值为yes。
(3) 检查从节点与新主节点的网络连通性
从节点执行telnet 新主节点IP 新主节点端口,确认端口可通;
关闭防火墙 / 安全组中拦截 Redis 端口的规则(生产环境建议仅开放主从、哨兵之间的端口)。
(4) 扩大新主节点的复制积压缓冲区
复制积压缓冲区过小,会导致从节点断线重连后无法做部分复制,触发全量复制时若 RDB 文件过大易失败;
调整配置:redis-cli -p 新主节点端口 CONFIG SET repl-backlog-size 1gb(根据业务量调整,默认 1MB),repl-backlog-ttl 86400(缓冲区过期时间)。
四、核心问题 4:哨兵节点自身无法加入集群,或与其他哨兵失联
现象
启动新哨兵节点后,INFO sentinel中sentinels数量未增加;或部分哨兵节点无法获取其他哨兵的状态,导致投票失败。
核心原因
- 哨兵的
master-name、master-ip、master-port配置与其他哨兵不一致 - 哨兵之间的 26379(默认)端口未互通,防火墙拦截
- 哨兵节点的
daemonize yes配置后,日志 /pid 文件权限不足,导致进程假死 - Redis 版本不一致(哨兵与主从、哨兵之间版本差异过大)
排查 & 解决步骤
(1) 统一所有哨兵的核心配置
所有哨兵对同一主节点的master-name、down-after-milliseconds、quorum必须完全一致,否则无法加入同一哨兵集群;
示例:所有哨兵都配置sentinel monitor mymaster 127.0.0.1 6379 2。
(2) 开放哨兵之间的通信端口
哨兵默认使用 26379 端口互相通信,需确保所有哨兵节点之间该端口可通;
临时关闭防火墙:systemctl stop firewalld(生产环境建议通过firewall-cmd开放指定端口)。
(3) 检查哨兵进程的文件权限
若哨兵配置了logfile和pidfile,需确保 Redis 用户有读写权限,否则进程启动后会立即退出;
示例:chown -R redis:redis /var/log/redis/ /var/run/redis/。
(4) 保证所有节点的 Redis 版本一致
生产环境建议哨兵、主节点、从节点使用同一稳定版本(如 6.2.8、7.0.12),避免版本差异导致的协议不兼容;
禁止混合使用低版本(如 3.2)和高版本(如 7.0)哨兵,会出现状态同步失败。
5、其他高频小问题
问题 1:主节点恢复后,自动成为新主节点的从节点,业务写入地址未更新
原因:客户端未适配哨兵的发布订阅机制 ,未监听+switch-master频道,导致不知道主节点地址变化;
解决方案:客户端使用支持哨兵自动发现的 Redis 客户端(如 Java 的 Jedis、Spring Data Redis),配置哨兵地址而非固定主节点地址。
问题 2:哨兵执行故障转移时,出现「NOGOODSLAVE」错误(日志中可见)
原因:所有从节点都被哨兵判定为 "不可用"(如优先级 0、同步延迟过高、宕机);
解决方案:参考「核心问题 1」的步骤 3,修复从节点的可用性。
问题 3:主从复制正常,但哨兵显示从节点数为 0
原因:哨兵连接主节点失败(如密码错误、网络不通),无法获取从节点信息;
解决方案:检查哨兵的auth-pass配置,确保哨兵能正常连接主节点(redis-cli -p 哨兵端口 SENTINEL ping返回PONG)。
6、哨兵模式生产环境避坑指南(预防问题比排查更重要)
- 部署规范 :哨兵节点数必须为奇数(3/5 个),与主从节点分开部署(避免主节点宕机导致哨兵同时宕机),同一机房部署即可,无需跨机房。
- 配置规范 :所有哨兵的
master-name、down-after-milliseconds、quorum完全一致 ,down-after-milliseconds建议≥30000ms,quorum设置为「哨兵节点数 / 2 +1」(如 3 个哨兵设为 2)。 - 权限规范:Redis 进程使用普通用户(如 redis)运行,日志 /pid/ 数据目录配置独立权限,避免权限不足导致进程假死。
- 网络规范 :仅开放主从、哨兵之间的 Redis 端口(6379/26379),禁止公网直接访问,配置
bind指定允许连接的 IP。 - 客户端规范 :禁止客户端直接配置主节点 IP,必须通过哨兵地址获取主节点,适配
+switch-master事件的自动重连。 - 监控规范 :监控哨兵的
INFO sentinel状态、主从节点的replication状态,监控日志中的「ODOWN」「FAILOVER」关键词,及时告警。 - 版本规范:统一 Redis 所有节点的版本,使用官方稳定版,避免使用测试版 / 开发版。
总结
- 哨兵模式是主从架构的高可用增强版,核心解决 "主节点宕机自动切换",但未解决数据分片和写扩展问题;
- 哨兵集群需部署奇数个(≥3),通过 "主观下线→客观下线→领头选举→故障转移" 实现自动化;
/ 数据目录配置独立权限,避免权限不足导致进程假死。 - 网络规范 :仅开放主从、哨兵之间的 Redis 端口(6379/26379),禁止公网直接访问,配置
bind指定允许连接的 IP。 - 客户端规范 :禁止客户端直接配置主节点 IP,必须通过哨兵地址获取主节点,适配
+switch-master事件的自动重连。 - 监控规范 :监控哨兵的
INFO sentinel状态、主从节点的replication状态,监控日志中的「ODOWN」「FAILOVER」关键词,及时告警。 - 版本规范:统一 Redis 所有节点的版本,使用官方稳定版,避免使用测试版 / 开发版。
总结
- 哨兵模式是主从架构的高可用增强版,核心解决 "主节点宕机自动切换",但未解决数据分片和写扩展问题;
- 哨兵集群需部署奇数个(≥3),通过 "主观下线→客观下线→领头选举→故障转移" 实现自动化;
- 哨兵模式适合中小规模 Redis 场景(数据量 GB 级),大规模分布式场景建议用 Redis Cluster。