Redis-哨兵
Redis 主从复制 + 哨兵(Sentinel)完整详解
前文已详细讲解 Redis 主从复制的核心流程,而主从复制仅能实现「数据备份+读写分离」,无法解决「主节点故障自动恢复」的问题——当 Master 宕机后,Slave 无法自动升级为 Master,整个集群会失去写能力。哨兵(Sentinel) 正是为解决这一问题而生,它是 Redis 高可用的核心组件,负责「监控主从节点、自动故障切换、通知客户端」,与主从复制结合,构成 Redis 高可用基础架构。
本文将在主从复制基础上,完整讲解哨兵的核心原理、架构、工作流程,以及主从+哨兵的联动逻辑、部署细节和避坑要点,确保覆盖从理论到实践的全维度。
第一部分:回顾 Redis 主从复制核心(衔接前文,避免脱节)
核心逻辑:Master 负责写操作,Slave 负责同步 Master 数据并提供读服务,通过「全量同步(首次连接)+ 增量同步(正常运行)」保证数据一致,核心依赖「复制缓冲区、偏移量(offset)、运行 ID(Run ID)」三个关键要素。
主从复制的局限性(哨兵解决的痛点):
- Master 故障后,无法自动切换到 Slave,需人工干预,可用性低;
- Slave 节点状态无统一监控,无法及时发现节点异常;
- 客户端无法自动感知 Master 切换,需手动修改连接地址。
第二部分:哨兵(Sentinel)核心详解
一、哨兵的核心定位与作用
Redis 哨兵(Sentinel)是一个「分布式监控+自动故障切换」组件,本质是一个运行在特殊模式下的 Redis 进程(并非独立服务),核心作用有 3 点:
- 监控(Monitoring):实时监控 Master、Slave 节点的运行状态(是否在线、是否正常提供服务);
- 自动故障切换(Automatic Failover):当 Master 宕机时,自动从 Slave 中选举一个最优节点升级为新 Master,同时让其他 Slave 同步新 Master 的数据;
- 通知(Notification):当节点状态发生变化(如 Master 宕机、新 Master 选举完成)时,通过配置的脚本或 API 通知客户端和运维人员。
补充:哨兵本身是分布式的,通常部署 3 个哨兵节点(避免单点故障),多个哨兵协同工作,确保故障判断的准确性和故障切换的可靠性。
二、哨兵架构(主从+哨兵联动架构)
标准高可用架构(生产环境推荐):1 个 Master + N 个 Slave + 3 个 Sentinel(奇数个,避免脑裂),架构图逻辑如下:
「哨兵集群」<--> 「主从集群」:
- 每个哨兵节点都与 Master、所有 Slave 建立长连接,实时发送 PING 命令检测节点状态;
- 哨兵之间也会建立长连接,互相交换节点状态信息,实现集群协同;
- 客户端不直接连接主从节点,而是连接哨兵集群,通过哨兵获取当前 Master 的地址,再与 Master 建立连接(实现自动切换感知)。
三、哨兵的核心工作流程(分 4 个阶段)
哨兵的工作流程围绕「监控→判断故障→选举新 Master→切换同步关系」展开,全程自动完成,无需人工干预,结合主从复制流程,完整逻辑如下:
阶段 1:初始化与监控(哨兵启动后持续运行)
- 哨兵启动时,会读取自身配置文件(sentinel.conf),获取 Master 的 IP、端口,以及需要监控的主从集群信息;
- 哨兵与 Master 建立 TCP 连接,发送 PING 命令(默认每 1 秒),检测 Master 状态;同时通过 Master 的 INFO 命令,获取所有 Slave 的地址,与每个 Slave 建立连接,同样以 1 秒间隔发送 PING 检测;
- 哨兵之间通过「发布/订阅」机制(基于 Master 的 __sentinel__:hello 频道)交换信息,包括自身的状态、对主从节点的监控结果,实现哨兵集群的协同;
- 主从节点会记录自身的状态(如 Master 的 offset、Slave 的同步进度),哨兵通过定期获取这些信息,维护整个集群的状态表。
阶段 2:故障检测与主观下线(SDOWN)
哨兵对节点的故障判断分为「主观下线」和「客观下线」,避免因网络波动误判故障:
- 主观下线(Subjective Down):单个哨兵在指定时间内(默认 30 秒,配置项:sentinel down-after-milliseconds <master-name> 30000),未收到 Master/Slave 的 PONG 响应,就会认为该节点「主观下线」(仅自身认为节点故障);
- 注意:网络波动可能导致短暂失联,因此单个哨兵的判断不具备权威性,需多个哨兵协同判断(客观下线)。
阶段 3:客观下线(ODOWN)与哨兵领导者选举
只有当 Master 被判断为「客观下线」后,才会触发故障切换,这一阶段是哨兵协同的核心:
- 客观下线(Objective Down):当一个哨兵判断 Master 主观下线后,会向其他哨兵发送「询问命令」,询问其他哨兵是否认为该 Master 下线;
- 若超过「法定人数」(配置项:sentinel quorum <master-name> 2,默认 2,即超过半数哨兵)都认为 Master 主观下线,则该 Master 被判定为「客观下线」(集群公认的故障);
- 哨兵领导者选举:客观下线后,需要从哨兵集群中选举一个「领导者哨兵」,由该哨兵负责执行后续的故障切换(避免多个哨兵同时执行切换,导致混乱);
-
选举规则(Raft 算法简化版):
- 每个哨兵都可以发起选举请求,获得超过半数哨兵投票的哨兵,成为领导者;
- 若未选出领导者,重新发起选举,直到选出为止(确保有且仅有一个领导者)。
阶段 4:故障切换(核心流程,与主从复制联动)
领导者哨兵负责执行故障切换,全程自动完成,分为 5 步,紧密结合主从复制的同步逻辑:
-
筛选合格 Slave:从所有 Slave 中,排除以下节点,筛选出可升级为 Master 的候选节点:
- 处于主观下线状态的 Slave(本身故障);
- 与 Master 断开连接时间过长的 Slave(数据过于陈旧,配置项:sentinel min-replicas-to-write 1,可自定义阈值);
- 优先级过低的 Slave(配置项:slave-priority,默认 100,优先级越低,越难被选中)。
-
选举新 Master:从候选 Slave 中,按以下优先级选举最优节点作为新 Master(优先级从高到低):
- 1. 优先级(slave-priority):数值越小,优先级越高;
- 2. 复制偏移量(offset):偏移量越大,说明同步 Master 数据越完整;
- 3. 运行 ID(Run ID):运行 ID 越小,优先级越高(兜底规则,避免并列)。
-
执行切换:让候选 Slave 升级为新 Master:
- 领导者哨兵向候选 Slave 发送「slaveof no one」命令,让该 Slave 停止同步旧 Master,升级为新 Master;
- 新 Master 启动后,将自身设为可读写(默认 Slave 只读,升级后自动切换为可读写)。
-
让其他 Slave 同步新 Master:
- 领导者哨兵向其他所有 Slave 发送「slaveof <新 Master IP> <新 Master 端口>」命令;
- 这些 Slave 会与新 Master 建立连接,触发「全量同步」(若断线时间短,可触发部分同步),同步新 Master 的数据,成为新 Master 的 Slave;
- 此时,主从集群的结构更新为:新 Master + 原其他 Slave。
-
通知与清理:
- 领导者哨兵通过配置的「通知脚本」(sentinel notification-script),通知客户端和运维人员「Master 已切换」;
- 客户端通过哨兵获取新 Master 的地址,重新建立连接,实现「无感知切换」;
- 若旧 Master 后续恢复上线,哨兵会向其发送「slaveof <新 Master IP> <新 Master 端口>」命令,让旧 Master 成为新 Master 的 Slave(避免旧 Master 恢复后抢占主节点身份)。
补充:故障切换的时间通常在 10-30 秒(取决于配置和集群规模),期间集群会暂时失去写能力,但读能力可由 Slave 正常提供(前提是 Slave 未故障)。
四、哨兵核心配置(sentinel.conf)
哨兵的配置决定了监控精度、故障切换效率,以下是生产环境常用核心配置(注释清晰,可直接参考):
# 哨兵实例的端口(默认 26379,多个哨兵需配置不同端口)
port 26379
# 哨兵的工作目录(存放日志、临时文件)
dir /var/lib/redis/sentinel
# 监控的主节点:格式 [主节点名称] [主节点IP] [主节点端口] [法定人数]
# 主节点名称:自定义(如 mymaster),用于标识主从集群
# 法定人数:判断 Master 客观下线所需的哨兵数量(推荐 2,3 个哨兵时)
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点密码(若 Master 配置了 requirepass,必须配置)
sentinel auth-pass mymaster 123456
# 节点主观下线时间(毫秒),默认 30000 毫秒(30 秒)
sentinel down-after-milliseconds mymaster 30000
# 故障切换超时时间(毫秒),默认 180000 毫秒(3 分钟)
# 超过该时间,故障切换未完成,则视为失败,重新发起切换
sentinel failover-timeout mymaster 180000
# 故障切换时,最多允许多少个 Slave 同时同步新 Master(默认 1)
# 数值越大,切换速度越快,但会占用更多带宽,建议 1-2
sentinel parallel-syncs mymaster 1
# 通知脚本(可选):节点状态变化时,执行该脚本通知运维(如发送邮件、短信)
sentinel notification-script mymaster /usr/local/redis/sentinel/notify.sh
第三部分:主从复制 + 哨兵 完整部署示例(实战落地)
以「1 Master + 2 Slave + 3 Sentinel」为例,讲解部署步骤(Linux 环境,Redis 6.2 版本),确保可直接落地:
一、环境准备(3 台服务器,也可单机多实例)
|
节点类型
|
IP 地址
|
端口
|
角色
|
|---|---|---|---|
|
主节点
|
192.168.1.10
|
6379
|
Master
|
|
从节点1
|
192.168.1.11
|
6379
|
Slave
|
|
从节点2
|
192.168.1.12
|
6379
|
Slave
|
|
哨兵1
|
192.168.1.10
|
26379
|
Sentinel
|
|
哨兵2
|
192.168.1.11
|
26379
|
Sentinel
|
|
哨兵3
|
192.168.1.12
|
26379
|
Sentinel
|
二、部署主从复制(参考前文,简化步骤)
-
部署 Master(192.168.1.10):
- 修改 redis.conf:开启 daemonize yes,配置 requirepass 123456(可选,推荐);
- 启动 Master:redis-server /etc/redis/redis.conf。
-
部署 2 个 Slave(192.168.1.11、192.168.1.12):
- 修改 redis.conf:daemonize yes,添加 replicaof 192.168.1.10 6379,配置 masterauth 123456;
- 启动 Slave:redis-server /etc/redis/redis.conf;
- 验证:在 Master 执行 info replication,查看 slave0、slave1 的状态(connected_slaves=2 即为正常)。
三、部署哨兵集群(3 个节点,配置相同)
- 在 3 台服务器上,分别创建哨兵配置文件 sentinel.conf(路径:/etc/redis/sentinel.conf),配置内容如下:
port 26379dir /var/lib/redis/sentinelsentinel monitor mymaster 192.168.1.10 6379 2sentinel auth-pass mymaster 123456sentinel down-after-milliseconds mymaster 30000sentinel failover-timeout mymaster 180000sentinel parallel-syncs mymaster 1 - 启动 3 个哨兵(分别在 3 台服务器执行):
redis-sentinel /etc/redis/sentinel.conf -
验证哨兵集群:
- 在任意哨兵节点执行:redis-cli -p 26379 info sentinel;
- 查看结果:sentinel_masters=1(监控 1 个主集群),sentinel_slaves=2(2 个 Slave),sentinel_sentinels=3(3 个哨兵),即为正常。
四、故障切换测试(验证高可用)
- 模拟 Master 故障:在 Master 节点(192.168.1.10)执行:redis-cli -a 123456 shutdown;
- 观察哨兵日志(路径:/var/lib/redis/sentinel/redis-sentinel.log),会看到「主观下线→客观下线→选举领导者→故障切换」的完整日志;
-
验证切换结果:
- 在任意哨兵节点执行:redis-cli -p 26379 sentinel get-master-addr-by-name mymaster;
- 会返回新 Master 的 IP 和端口(如 192.168.1.11 6379);
- 在新 Master 执行 info replication,会看到 role:master,connected_slaves=1(另一个 Slave 已同步,旧 Master 未恢复);
- 恢复旧 Master:执行 redis-server /etc/redis/redis.conf,再次查看新 Master 的 info replication,会发现旧 Master 已成为新 Master 的 Slave。
第四部分:核心注意事项与避坑要点
一、主从复制 + 哨兵的关键避坑点
- 哨兵数量必须为奇数:避免脑裂(如 2 个哨兵,可能出现各自选举领导者,导致切换混乱),推荐 3 个哨兵;
- 法定人数(quorum)配置合理:3 个哨兵时,quorum 设为 2(超过半数);5 个哨兵时,设为 3,确保故障判断的准确性;
- Slave 优先级配置:根据业务需求设置 slave-priority,核心 Slave(数据完整、性能好)设为高优先级(数值小),避免性能差的 Slave 被选为新 Master;
- 复制缓冲区调优:Master 的 repl-backlog-size 调大(如 10MB),减少 Slave 断线重连时的全量同步概率,提升同步效率;
- 密码一致性:Master、Slave、哨兵的密码必须一致(Master 设 requirepass,Slave 设 masterauth,哨兵设 sentinel auth-pass),否则会导致同步失败、哨兵监控失败;
- 避免单点故障:哨兵和 Slave 尽量部署在不同服务器,避免一台服务器宕机,导致多个节点失效。
二、常见问题排查
- 哨兵无法监控主节点:检查 Master 密码是否正确、网络是否通畅(防火墙开放 6379、26379 端口)、哨兵配置中的 Master IP/端口是否正确;
- 故障切换失败:查看哨兵日志,排查是否有合格的 Slave、哨兵领导者选举是否成功、故障切换超时时间是否过短;
- Slave 同步延迟过大:优化 Master 写性能、增加 Slave 节点分担读压力、调大复制缓冲区、检查网络带宽;
- 旧 Master 恢复后抢占主节点:无需担心,哨兵会自动将旧 Master 设为新 Master 的 Slave,确保集群结构稳定。
第五部分:总结
Redis 主从复制 + 哨兵,是 Redis 高可用的基础架构,核心逻辑是:
- 主从复制:负责「数据备份+读写分离」,通过全量+增量同步保证数据一致,解决数据冗余和读负载问题;
- 哨兵:负责「监控+自动故障切换+通知」,解决主节点故障后的自动恢复问题,实现集群高可用;
- 两者联动:哨兵依赖主从复制的同步机制,故障切换后重新构建主从关系;主从复制依赖哨兵实现故障后的自动升级,两者缺一不可。
生产环境中,主从+哨兵架构可满足大部分中小规模业务的高可用需求(99.9% 可用性);若业务规模较大、并发量高,可在此基础上升级为 Redis Cluster(集群),实现分片存储和更高的可用性。

浙公网安备 33010602011771号