RedisNotes

第 18 章:哨兵原理

zjc 于 2026-01-18 发布

这是《Redis 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 主从复制只提供副本,不提供自动故障切换。Sentinel 负责监控、通知、配置发现和自动切主,是中小 Redis 集群的高可用方案。

18.1 Sentinel 架构

        Sentinel1       Sentinel2       Sentinel3
            |               |               |
            +-------+-------+-------+-------+
                    v               v
                  Master --------> Replica1
                                  Replica2

Sentinel 不代理业务流量,客户端仍然直连 Redis。它提供:

  1. 监控主从节点;
  2. 判断主观/客观下线;
  3. 选举 Leader Sentinel;
  4. 执行故障转移;
  5. 通知客户端新 Master 地址。

18.2 部署要求

至少 3 个奇数节点,且不要与 Redis Master 同机部署。

sentinel.conf

port 26379
sentinel monitor mymaster 192.168.1.10 6379 2
sentinel auth-pass mymaster redis123
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

参数说明:

配置 含义
mymaster master 名称,客户端使用
2 quorum,客观下线票数
down-after-milliseconds 无响应判定主观下线
failover-timeout 故障转移超时
parallel-syncs 切主后同时重连新主的从节点数

启动:

redis-sentinel sentinel.conf
# 或
redis-server sentinel.conf --sentinel

18.3 主观下线与客观下线

主观下线 SDOWN

单个 Sentinel 在 down-after-milliseconds 内未收到有效回复:

Sentinel1 认为 Master down

可能是网络分区或本机问题,不足以切主。

客观下线 ODOWN

至少 quorum 个 Sentinel 都认为主下线:

quorum=2,两个 Sentinel 都 SDOWN -> ODOWN

quorum 不是执行切换所需票数,而是“客观下线判定票数”。

18.4 Sentinel Leader 选举

客观下线后,Sentinel 之间通过类 Raft 选举选出 Leader 执行故障转移:

  1. 每个 Sentinel 都可能成为候选;
  2. 需要获得多数 Sentinel 授权;
  3. 每轮纪元递增;
  4. Leader 执行切主。

因此通常部署至少 3 个节点,容忍 1 个 Sentinel 故障;5 个容忍 2 个。

18.5 故障转移流程

1. Master 被判定 ODOWN
2. Sentinel 选举 Leader
3. Leader 从可用 Replica 中选择新 Master
4. 对选中的 Replica 执行 SLAVEOF NO ONE
5. 其他 Replica 执行 SLAVEOF new-master
6. 旧 Master 恢复后也变成 Replica
7. Sentinel 更新配置与纪元
8. 客户端感知新地址

选择新 Master 时考虑:

配置:

replica-priority 100

0 表示永不参与选举。

18.6 客户端如何接入 Sentinel

Jedis:

Set<String> sentinels = Set.of(
        "s1:26379", "s2:26379", "s3:26379");

JedisSentinelPool pool = new JedisSentinelPool(
        "mymaster", sentinels, "default", "redis123");

Lettuce:

RedisURI uri = RedisURI.Builder.sentinel("s1", 26379, "mymaster")
        .withSentinel("s2", 26379)
        .withSentinel("s3", 26379)
        .withAuthentication("default", "redis123")
        .build();

客户端流程:

连接 Sentinel -> 查询 mymaster 当前 Master
               -> 直连 Master
               -> 订阅 switch-master 事件
               -> 切换后重建连接

18.7 Sentinel 常用命令

SENTINEL masters
SENTINEL master mymaster
SENTINEL replicas mymaster
SENTINEL sentinels mymaster
SENTINEL get-master-addr-by-name mymaster
SENTINEL ckquorum mymaster
SENTINEL reset mymaster
SENTINEL failover mymaster

SENTINEL ckquorum 检查当前可用 Sentinel 是否满足故障切换多数派。

18.8 脑裂与数据丢失

异步复制下的风险:

1. Master 与多数 Sentinel/Replica 网络分区
2. 旧 Master 仍接受客户端写
3. Sentinel 选出新 Master
4. 网络恢复,旧 Master 降级为 Replica
5. 旧 Master 分区期间写入丢失

缓解配置:

min-replicas-to-write 1
min-replicas-max-lag 10

含义:至少有 1 个从节点延迟小于 10 秒,Master 才接受写。它降低脑裂风险,但牺牲部分可用性。

业务侧必须:

18.9 故障演练

初始:
  Master A, Replica B/C

动作:
  kill A

观察:
  1. Sentinel SDOWN/ODOWN 日志
  2. Leader 选举
  3. B/C 谁成为 Master
  4. 客户端是否自动切换
  5. 写入是否恢复
  6. A 恢复后是否变成 Replica

恢复旧 Master:

systemctl start redis

Sentinel 会自动将其配置为新 Master 的从节点。

18.10 Sentinel 与 Cluster 怎么选

维度 Sentinel 主从 Cluster
分片 不支持 支持 16384 slots
容量 单机内存上限 多节点水平扩展
客户端 Sentinel 协议 Cluster 协议/重定向
多 key 操作 无槽限制 通常需同槽
运维复杂度 较低 较高
适合 中等容量高可用 大容量高吞吐

如果单实例容量与写入压力足够,优先 Sentinel;超过单机瓶颈或需要水平拆分,再上 Cluster。

本章小结

思考题

  1. quorum=2 且只有两个 Sentinel,为什么仍然不推荐?
  2. 故障切换后客户端为什么会短暂报错?如何降低影响?
  3. min-replicas-to-write 如何降低脑裂丢失风险?代价是什么?