《Redis Sentinel 高可用:监控、故障转移与生产运维》

深入 Redis Sentinel 的角色与架构、quorum 投票与主观/客观下线判定、故障转移完整流程、客户端重定向机制,以及 3 节点生产部署的配置、监控与常见坑。

一、Sentinel 的角色与架构

1.1 Sentinel 是什么

Sentinel 是 Redis 官方提供的高可用解决方案,解决主从复制中主节点故障时的自动切换问题。它本质上是独立运行的 Redis 进程(默认端口 26379),不存业务数据,只负责监控、通知、自动故障转移和配置提供四大职能。

# 以 Sentinel 模式启动
redis-sentinel /etc/redis/sentinel.conf
redis-server /etc/redis/sentinel.conf --sentinel

Sentinel 是"监控哨兵"而非"数据节点"。它的内存占用极小(通常几十 MB),但承担了「主节点故障后谁接管」这个关键决策,因此必须以奇数个节点集群部署,绝不能单点运行。

1.2 三种角色协同

一套 Sentinel 体系由三类进程组成:

角色端口职责数量
Master6379提供读写,被保护对象1
Replica6379数据冗余,故障转移候选1~N
Sentinel26379监控、选举、故障转移、服务发现≥3(奇数)
# 典型拓扑:1 主 2 从 3 哨兵
# 节点 A: Master 10.0.0.1:6379 + Sentinel 26379
# 节点 B: Replica 10.0.0.2:6379 + Sentinel 26379
# 节点 C: Replica 10.0.0.3:6379 + Sentinel 26379

1.3 为什么需要三个哨兵

故障转移的正确性依赖多数派决策。1 个哨兵自身宕机即失明;2 个哨兵可能各执一词无法达成多数。3 个是能容忍 1 个哨兵宕机的最小奇数规模。

部署原则:3 个 Sentinel 应分布在不同物理机/可用区,避免机架断电同时宕机。容忍 1 个哨兵故障 → 至少 3 个;容忍 2 个 → 至少 5 个。

二、quorum 与投票机制

2.1 quorum 的含义

quorum(法定票数)是 Sentinel 判定主节点客观下线所需的最少同意票数:

# 监控主节点 mymaster,quorum 为 2
sentinel monitor mymaster 10.0.0.1 6379 2

quorum 有两层语义:一是至少 quorum 个 Sentinel 认为主节点主观下线,才触发客观下线;二是被推举为 leader 的 Sentinel 需获得至少 max(quorum, N/2+1) 票才能执行故障转移。

redis-cli -p 26379 sentinel master mymaster
# 输出包含 quorum、num-other-sentinel-down 等字段

2.2 leader 选举流程

判定客观下线后,发起一次领导者选举(类似 Raft 选主):

  1. 每个 Sentinel 随机延迟 0~5 秒后自荐为 leader。
  2. 每个配置纪元(epoch)只能投一票,先到先得。
  3. 获得多数派(N/2+1)投票的 Sentinel 成为 leader。
  4. leader 负责执行故障转移,其他 Sentinel 跟随结果。
# 观察选举纪元与当前主节点
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
# 成功输出新主 ip 与 port

2.3 quorum 数值的取舍

部署规模推荐 quorum容忍故障
3 哨兵21 个哨兵
5 哨兵32 个哨兵
7 哨兵43 个哨兵
# quorum=3(3 哨兵)的后果:2 个哨兵失联即无法触发故障转移
# quorum=1 的后果:单个哨兵网络分区即可误判,可能误触发切换

生产环境 3 哨兵 + quorum=2 最常见。quorum 在「避免单点误判」与「快速响应故障」之间取平衡。

三、主观下线与客观下线

3.1 主观下线 S_DOWN

每个 Sentinel 通过心跳 PING 感知主节点状态。在 down-after-milliseconds(默认 30 秒)内无有效回复,即单方面标记主观下线(S_DOWN):

# 10 秒无响应即判定主观下线
sentinel down-after-milliseconds mymaster 10000

3.2 客观下线 O_DOWN

主观下线只是局部判断,可能因网络分区或哨兵误判产生。当至少 quorum 个 Sentinel 都确认该主节点主观下线时,才标记客观下线(O_DOWN),从而允许启动故障转移。

对比项主观下线 S_DOWN客观下线 O_DOWN
判定主体单个 Sentinel≥quorum 个 Sentinel
触发动作记录状态、发通知触发选举与故障转移
可逆性PING 恢复后自动清除由新主替代

3.3 判定参数详解

sentinel down-after-milliseconds mymaster 10000   # 无响应多久算主观下线
sentinel failover-timeout mymaster 180000         # 故障转移超时(默认 3 分钟)
sentinel parallel-syncs mymaster 1                # 切换后同时同步的从节点数

跨机房部署时 down-after-milliseconds 应适当加大(如 30s),避免瞬时抖动触发无谓切换。故障转移本身有代价——客户端重连、短暂不可用,因此宁慢勿快是生产经验。

四、故障转移流程

4.1 从节点筛选

leader 执行故障转移时,第一步从候选从节点里挑选最优者:

  1. 剔除断线、主观下线、最近连不上的从节点。
  2. 剔除 slave-priority 为 0 的从节点(0 表示永不提升)。
  3. 剔除复制偏移量落后的从节点(数据越新越优)。
  4. 优先选择优先级数值小(高优先级)的从节点。
slave-priority 100   # 数值越小优先级越高
slave-priority 0     # 永不被提升

4.2 从节点选举与提升

# leader 自动执行(无需人工干预)
SLAVEOF NO ONE                     # 候选从节点断开复制成为新主
CONFIG REWRITE                     # 持久化配置
# 通知其他从节点指向新主
SLAVEOF <new-master-ip> <new-master-port>
# 观察切换事件
redis-cli -p 26379 sentinel events mymaster
# +switch-master mymaster 10.0.0.1 6379 10.0.0.2 6379

4.3 完整时序

T+0s    主节点宕机
T+10s   每个哨兵判定主观下线(down-after-milliseconds=10s)
T+15s   达到 quorum=2,标记客观下线
T+15s   leader 选举,多数票胜出
T+17s   SLAVEOF NO ONE 提升候选为新主
T+18s   通知其他从节点复制新主
T+20s   更新配置纪元,客户端获取新主地址

从宕机到新主可用通常需要 down-after-milliseconds + 选举时间 + 提升时间,生产一般 10~30 秒。缩短判定时间可加快切换,但会增加误判风险。

五、客户端重定向

5.1 服务发现

Sentinel 的核心价值之一是配置提供:客户端不硬编码主节点地址,而是连接任意 Sentinel 动态获取当前主节点:

redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
# 1) "10.0.0.2"
# 2) "6379"

redis-cli -p 26379 sentinel replicas mymaster   # 所有从节点
redis-cli -p 26379 sentinel sentinels mymaster  # 所有哨兵

5.2 客户端实现

主流客户端(Lettuce、Jedis、go-redis、redis-py、ioredis)都内置 Sentinel 模式:

// Java 示例(Lettuce / Spring Data Redis)
RedisURI uri = RedisURI.Builder
    .sentinel("10.0.0.1", 26379, "mymaster")
    .withSentinel("10.0.0.2", 26379)
    .withSentinel("10.0.0.3", 26379)
    .build();
RedisClient client = RedisClient.create(uri);
客户端感知机制重连行为
Lettuce轮询 sentinel get-master-addr-by-name自动切换连接
Jedis哨兵连接池,故障时重查需配置重试
go-redis每次通过 Sentinel 解析自动刷新主地址
redis-pySentinel 对象代理连接自动重定向

客户端必须配置多个 Sentinel 地址,否则某个哨兵宕机时客户端失去服务发现能力。连接超时与重试参数应覆盖故障转移窗口。

六、3 节点生产部署

6.1 主从配置

# 主节点 redis.conf
bind 0.0.0.0
port 6379
appendonly yes
min-replicas-to-write 1          # 脑裂防护,见第八章
min-replicas-max-lag 10

# 从节点 redis.conf(10.0.0.2 / 10.0.0.3)
replicaof 10.0.0.1 6379
replica-read-only yes
replica-priority 100
# 验证复制状态
redis-cli -p 6379 info replication
# role:master
# connected_slaves:2
# slave0:ip=10.0.0.2,port=6379,state=online,offset=1234,lag=0

6.2 Sentinel 配置

# 每台机器上的 sentinel.conf
port 26379
sentinel monitor mymaster 10.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster <password>
sentinel announce-ip 10.0.0.x            # 本机公网/内网地址
# 启动并验证哨兵互相发现
redis-server /etc/redis/sentinel.conf --sentinel
redis-cli -p 26379 sentinel sentinels mymaster   # 应列出另外两个哨兵

主节点配置 requirepass 时,Sentinel 必须通过 sentinel auth-pass 提供密码,否则监控失效。announce-ip 在 NAT/云负载均衡环境下必须显式配置。

七、Sentinel 命令与 API

7.1 常用运维命令

redis-cli -p 26379 sentinel get-master-addr-by-name mymaster   # 当前主节点
redis-cli -p 26379 sentinel master mymaster                    # 主节点信息
redis-cli -p 26379 sentinel masters                            # 所有被监控主节点
redis-cli -p 26379 sentinel failover mymaster                  # 手动强制切换
redis-cli -p 26379 sentinel set mymaster down-after-milliseconds 5000

7.2 动态调整

命令作用是否在线生效
sentinel failover手动触发故障转移是
sentinel set修改运行配置是
sentinel flushconfig持久化到配置文件是
sentinel monitor/unmonitor添加/移除监控是

sentinel failover 是演练和人为切换主节点的利器:无需真宕主节点即可验证整套切换链路。

八、常见坑与避坑

8.1 脑裂问题

主节点与多数哨兵网络分区时,原主仍对外写服务,同时哨兵将某从节点提升为新主 → 出现两个主节点,数据分叉。缓解手段:

# 主节点要求至少写入 1 个副本才返回成功
min-replicas-to-write 1
min-replicas-max-lag 10

失联副本超过阈值时主节点拒绝写请求,从源头避免脑裂期间写入孤儿数据。

8.2 配置与运维坑

坑症状规避
monitor 里主节点地址写错哨兵误报 down核对 ip/port
客户端只配一个哨兵该哨兵宕机后无法感知配置全部哨兵地址
主从在同一物理机机架断电全挂跨机架/可用区部署
down-after-milliseconds 太小抖动频繁切换结合网络延迟调大
从节点允许写入切换后数据不一致保持 replica-read-only yes
不演练真正故障时才发现配置错误定期 failover 演练

生产经验:Sentinel 体系每季度至少做一次故障转移演练,检查新主数据完整性、从节点自动指向新主、客户端自动恢复、告警正确触发。

九、监控与运维实践

9.1 关键监控指标

redis-cli -p 26379 info sentinel
# sentinel_masters:1
# sentinel_tilt:0
# sentinel_running_scripts:0
指标正常值告警阈值
sentinel_masters与配置一致变化即告警
sentinel_tilt0>0 进入倾斜模式告警
主节点状态oks_down / o_down 告警
复制延迟 lag<1s>5s 告警
从节点在线数≥2<2 告警

9.2 告警与演练

# Prometheus 告警示例:主节点客观下线 30 秒未恢复
alert: RedisMasterDown
expr: redis_sentinel_master_is_down{master="mymaster"} == 1
for: 30s
labels: {severity: critical}

# 演练 1:手动故障转移
redis-cli -p 26379 sentinel failover mymaster

# 演练 2:拔掉主节点电源,观察切换耗时与数据丢失窗口
# 演练 3:原主恢复后核对数据一致性,应自动降级为从节点

演练必须记录每次切换耗时与数据丢失窗口,据此调优参数。业务上需提前决策「要可用还是要数据」——min-replicas-to-write 会在极端情况牺牲可用性换取数据不丢。

结语

  1. Sentinel 是 Redis 高可用核心,由监控、通知、自动故障转移、配置提供四部分职能组成,必须奇数个哨兵部署以避免单点。
  2. quorum 决定客观下线与故障转移授权门槛,3 哨兵 + quorum=2 是最常见生产配置。
  3. 主观下线是单哨兵判断,客观下线需要多数派共识,两者不可混淆。
  4. 故障转移包括从节点筛选、选举提升与其余从节点重定向,总耗时约 10~30 秒。
  5. 客户端通过 sentinel get-master-addr-by-name 动态发现主节点,必须配置多个哨兵地址并设置合理重试。
  6. 脑裂风险可通过 min-replicas-to-write 缓解,写入前要求至少一个副本在线。
  7. 生产部署遵循「1 主 2 从 3 哨兵」跨机架/可用区拓扑,并定期进行故障转移演练。
  8. 监控聚焦哨兵状态、复制延迟、下线标志与从节点在线数,结合 Prometheus 与告警规则闭环。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「redis」更多文章

  1. 《Redis 容灾与备份恢复:RDB/AOF 备份、复制与演练》
  2. 《Redis 对象编码与内存优化:listpack 与编码转型》
  3. 《Redis 管道、事务与批量优化:从 N 次 RTT 到一次》