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 点:
  1. 监控(Monitoring):实时监控 Master、Slave 节点的运行状态(是否在线、是否正常提供服务);
  2. 自动故障切换(Automatic Failover):当 Master 宕机时,自动从 Slave 中选举一个最优节点升级为新 Master,同时让其他 Slave 同步新 Master 的数据;
  3. 通知(Notification):当节点状态发生变化(如 Master 宕机、新 Master 选举完成)时,通过配置的脚本或 API 通知客户端和运维人员。
补充:哨兵本身是分布式的,通常部署 3 个哨兵节点(避免单点故障),多个哨兵协同工作,确保故障判断的准确性和故障切换的可靠性。

二、哨兵架构(主从+哨兵联动架构)

标准高可用架构(生产环境推荐):1 个 Master + N 个 Slave + 3 个 Sentinel(奇数个,避免脑裂),架构图逻辑如下:
「哨兵集群」<--> 「主从集群」:
  • 每个哨兵节点都与 Master、所有 Slave 建立长连接,实时发送 PING 命令检测节点状态;
  • 哨兵之间也会建立长连接,互相交换节点状态信息,实现集群协同;
  • 客户端不直接连接主从节点,而是连接哨兵集群,通过哨兵获取当前 Master 的地址,再与 Master 建立连接(实现自动切换感知)。

三、哨兵的核心工作流程(分 4 个阶段)

哨兵的工作流程围绕「监控→判断故障→选举新 Master→切换同步关系」展开,全程自动完成,无需人工干预,结合主从复制流程,完整逻辑如下:

阶段 1:初始化与监控(哨兵启动后持续运行)

  1. 哨兵启动时,会读取自身配置文件(sentinel.conf),获取 Master 的 IP、端口,以及需要监控的主从集群信息;
  2. 哨兵与 Master 建立 TCP 连接,发送 PING 命令(默认每 1 秒),检测 Master 状态;同时通过 Master 的 INFO 命令,获取所有 Slave 的地址,与每个 Slave 建立连接,同样以 1 秒间隔发送 PING 检测;
  3. 哨兵之间通过「发布/订阅」机制(基于 Master 的 __sentinel__:hello 频道)交换信息,包括自身的状态、对主从节点的监控结果,实现哨兵集群的协同;
  4. 主从节点会记录自身的状态(如 Master 的 offset、Slave 的同步进度),哨兵通过定期获取这些信息,维护整个集群的状态表。

阶段 2:故障检测与主观下线(SDOWN)

哨兵对节点的故障判断分为「主观下线」和「客观下线」,避免因网络波动误判故障:
  1. 主观下线(Subjective Down):单个哨兵在指定时间内(默认 30 秒,配置项:sentinel down-after-milliseconds <master-name> 30000),未收到 Master/Slave 的 PONG 响应,就会认为该节点「主观下线」(仅自身认为节点故障);
  2. 注意:网络波动可能导致短暂失联,因此单个哨兵的判断不具备权威性,需多个哨兵协同判断(客观下线)。

阶段 3:客观下线(ODOWN)与哨兵领导者选举

只有当 Master 被判断为「客观下线」后,才会触发故障切换,这一阶段是哨兵协同的核心:
  1. 客观下线(Objective Down):当一个哨兵判断 Master 主观下线后,会向其他哨兵发送「询问命令」,询问其他哨兵是否认为该 Master 下线;
  2. 若超过「法定人数」(配置项:sentinel quorum <master-name> 2,默认 2,即超过半数哨兵)都认为 Master 主观下线,则该 Master 被判定为「客观下线」(集群公认的故障);
  3. 哨兵领导者选举:客观下线后,需要从哨兵集群中选举一个「领导者哨兵」,由该哨兵负责执行后续的故障切换(避免多个哨兵同时执行切换,导致混乱);
  4. 选举规则(Raft 算法简化版):
    1. 每个哨兵都可以发起选举请求,获得超过半数哨兵投票的哨兵,成为领导者;
    2. 若未选出领导者,重新发起选举,直到选出为止(确保有且仅有一个领导者)。

阶段 4:故障切换(核心流程,与主从复制联动)

领导者哨兵负责执行故障切换,全程自动完成,分为 5 步,紧密结合主从复制的同步逻辑:
  1. 筛选合格 Slave:从所有 Slave 中,排除以下节点,筛选出可升级为 Master 的候选节点:
    1. 处于主观下线状态的 Slave(本身故障);
    2. 与 Master 断开连接时间过长的 Slave(数据过于陈旧,配置项:sentinel min-replicas-to-write 1,可自定义阈值);
    3. 优先级过低的 Slave(配置项:slave-priority,默认 100,优先级越低,越难被选中)。
  2. 选举新 Master:从候选 Slave 中,按以下优先级选举最优节点作为新 Master(优先级从高到低):
    1. 1. 优先级(slave-priority):数值越小,优先级越高;
    2. 2. 复制偏移量(offset):偏移量越大,说明同步 Master 数据越完整;
    3. 3. 运行 ID(Run ID):运行 ID 越小,优先级越高(兜底规则,避免并列)。
  3. 执行切换:让候选 Slave 升级为新 Master
    1. 领导者哨兵向候选 Slave 发送「slaveof no one」命令,让该 Slave 停止同步旧 Master,升级为新 Master;
    2. 新 Master 启动后,将自身设为可读写(默认 Slave 只读,升级后自动切换为可读写)。
  4. 让其他 Slave 同步新 Master
    1. 领导者哨兵向其他所有 Slave 发送「slaveof <新 Master IP> <新 Master 端口>」命令;
    2. 这些 Slave 会与新 Master 建立连接,触发「全量同步」(若断线时间短,可触发部分同步),同步新 Master 的数据,成为新 Master 的 Slave;
    3. 此时,主从集群的结构更新为:新 Master + 原其他 Slave。
  5. 通知与清理
    1. 领导者哨兵通过配置的「通知脚本」(sentinel notification-script),通知客户端和运维人员「Master 已切换」;
    2. 客户端通过哨兵获取新 Master 的地址,重新建立连接,实现「无感知切换」;
    3. 若旧 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

二、部署主从复制(参考前文,简化步骤)

  1. 部署 Master(192.168.1.10):
    1. 修改 redis.conf:开启 daemonize yes,配置 requirepass 123456(可选,推荐);
    2. 启动 Master:redis-server /etc/redis/redis.conf。
  2. 部署 2 个 Slave(192.168.1.11、192.168.1.12):
    1. 修改 redis.conf:daemonize yes,添加 replicaof 192.168.1.10 6379,配置 masterauth 123456;
    2. 启动 Slave:redis-server /etc/redis/redis.conf;
    3. 验证:在 Master 执行 info replication,查看 slave0、slave1 的状态(connected_slaves=2 即为正常)。

三、部署哨兵集群(3 个节点,配置相同)

  1. 在 3 台服务器上,分别创建哨兵配置文件 sentinel.conf(路径:/etc/redis/sentinel.conf),配置内容如下: port 26379 dir /var/lib/redis/sentinel sentinel monitor mymaster 192.168.1.10 6379 2 sentinel auth-pass mymaster 123456 sentinel down-after-milliseconds mymaster 30000 sentinel failover-timeout mymaster 180000 sentinel parallel-syncs mymaster 1
  2. 启动 3 个哨兵(分别在 3 台服务器执行): redis-sentinel /etc/redis/sentinel.conf
  3. 验证哨兵集群:
    1. 在任意哨兵节点执行:redis-cli -p 26379 info sentinel;
    2. 查看结果:sentinel_masters=1(监控 1 个主集群),sentinel_slaves=2(2 个 Slave),sentinel_sentinels=3(3 个哨兵),即为正常。

四、故障切换测试(验证高可用)

  1. 模拟 Master 故障:在 Master 节点(192.168.1.10)执行:redis-cli -a 123456 shutdown;
  2. 观察哨兵日志(路径:/var/lib/redis/sentinel/redis-sentinel.log),会看到「主观下线→客观下线→选举领导者→故障切换」的完整日志;
  3. 验证切换结果:
    1. 在任意哨兵节点执行:redis-cli -p 26379 sentinel get-master-addr-by-name mymaster;
    2. 会返回新 Master 的 IP 和端口(如 192.168.1.11 6379);
    3. 在新 Master 执行 info replication,会看到 role:master,connected_slaves=1(另一个 Slave 已同步,旧 Master 未恢复);
    4. 恢复旧 Master:执行 redis-server /etc/redis/redis.conf,再次查看新 Master 的 info replication,会发现旧 Master 已成为新 Master 的 Slave。

第四部分:核心注意事项与避坑要点

一、主从复制 + 哨兵的关键避坑点

  1. 哨兵数量必须为奇数:避免脑裂(如 2 个哨兵,可能出现各自选举领导者,导致切换混乱),推荐 3 个哨兵;
  2. 法定人数(quorum)配置合理:3 个哨兵时,quorum 设为 2(超过半数);5 个哨兵时,设为 3,确保故障判断的准确性;
  3. Slave 优先级配置:根据业务需求设置 slave-priority,核心 Slave(数据完整、性能好)设为高优先级(数值小),避免性能差的 Slave 被选为新 Master;
  4. 复制缓冲区调优:Master 的 repl-backlog-size 调大(如 10MB),减少 Slave 断线重连时的全量同步概率,提升同步效率;
  5. 密码一致性:Master、Slave、哨兵的密码必须一致(Master 设 requirepass,Slave 设 masterauth,哨兵设 sentinel auth-pass),否则会导致同步失败、哨兵监控失败;
  6. 避免单点故障:哨兵和 Slave 尽量部署在不同服务器,避免一台服务器宕机,导致多个节点失效。

二、常见问题排查

  1. 哨兵无法监控主节点:检查 Master 密码是否正确、网络是否通畅(防火墙开放 6379、26379 端口)、哨兵配置中的 Master IP/端口是否正确;
  2. 故障切换失败:查看哨兵日志,排查是否有合格的 Slave、哨兵领导者选举是否成功、故障切换超时时间是否过短;
  3. Slave 同步延迟过大:优化 Master 写性能、增加 Slave 节点分担读压力、调大复制缓冲区、检查网络带宽;
  4. 旧 Master 恢复后抢占主节点:无需担心,哨兵会自动将旧 Master 设为新 Master 的 Slave,确保集群结构稳定。

第五部分:总结

Redis 主从复制 + 哨兵,是 Redis 高可用的基础架构,核心逻辑是:
  1. 主从复制:负责「数据备份+读写分离」,通过全量+增量同步保证数据一致,解决数据冗余和读负载问题;
  2. 哨兵:负责「监控+自动故障切换+通知」,解决主节点故障后的自动恢复问题,实现集群高可用;
  3. 两者联动:哨兵依赖主从复制的同步机制,故障切换后重新构建主从关系;主从复制依赖哨兵实现故障后的自动升级,两者缺一不可。
生产环境中,主从+哨兵架构可满足大部分中小规模业务的高可用需求(99.9% 可用性);若业务规模较大、并发量高,可在此基础上升级为 Redis Cluster(集群),实现分片存储和更高的可用性。
posted @ 2026-03-14 19:46  ConfidentLiu  阅读(88)  评论(0)    收藏  举报