Skip to content

04.2 - 哨兵 Sentinel 机制

定位: Redis 的高可用守护进程——自动监控、自动故障转移、统一配置 面试高频度: ⭐⭐⭐⭐ 考查方式: 哨兵核心功能、主观下线 vs 客观下线、Raft 选主、脑裂问题


一、这是什么?为什么需要它?

是什么

Sentinel(哨兵)是一个分布式监控系统,对 Redis 主从集群进行监控、通知和自动故障转移。

为什么需要 Sentinel?

只有主从复制的问题:

  1. 主节点宕机:人工介入 → 选一个从节点 → 手动 SLAVEOF NO ONE → 其他从节点指向新主节点 → 通知客户端更新连接。整个过程 5-30 分钟的运维操作
  2. 无人值守的噩梦:半夜 3 点主节点挂了,在线业务全部写失败

Sentinel 的解决:

  1. 自动故障转移 → 30 秒内完成切换
  2. 通知客户端 → 通过 Pub/Sub 广播新主配置
  3. 哨兵本身高可用 → 至少 3 个哨兵实例
  4. 配置中心 → 客户端从哨兵获取主节点地址

二、原理拆解

2.1 哨兵架构

2.2 监控机制

Sentinel 的三种监控:

  1. 与主节点通信(每 10 秒 INFO + PING)→ 获取主从拓扑信息、发现新的从节点、检查主节点状态
  2. 与从节点通信(每 10 秒 INFO + PING)→ 获取从节点复制偏移量、检查从节点是否存活
  3. 哨兵间通信(Pub/Sub 频道 sentinel:hello)→ 每 2 秒发布自己的信息、订阅其他哨兵的信息、交换对主节点的"看法"

2.3 主观下线 vs 客观下线

为什么需要 quorum? 防止误判:一个哨兵网络抖动 ≠ 真的挂了。quorum 个哨兵确认后才触发切换。但也只是触发,实际切换需要多数派哨兵同意

2.4 故障转移流程

故障转移的完整 5 步:

整个过程:正常情况下 10-30 秒完成

2.5 脑裂问题

恢复后: 旧主恢复连接 → 发现自己不在集群中 → 变成新主的从节点 → 旧主上分区期间的写入数据被丢弃!

如何缓解脑裂:

  • min-slaves-to-write 1 — 至少 1 个从节点正常才写
  • min-slaves-max-lag 10 — 从节点 lag ≤ 10 秒
  • 配置生效后,网络分区期间旧主的写入会失败,保证数据一致性(以新主为准)

三、图解全景


四、实战验证

4.1 启动哨兵

bash
# 1. 启动主从(单机模拟)
redis-server --port 6379
redis-server --port 6380 --slaveof 127.0.0.1 6379
redis-server --port 6381 --slaveof 127.0.0.1 6379

# 2. 创建哨兵配置文件
cat > /tmp/sentinel.conf << 'EOF'
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 30000
sentinel parallel-syncs mymaster 1
EOF

# 3. 启动哨兵
redis-server /tmp/sentinel.conf --sentinel

# 4. 查看哨兵信息
redis-cli -p 26379 SENTINEL masters
# 1) 1) "name"
#    2) "mymaster"
#    3) "ip"
#    4) "127.0.0.1"
#    5) "port"
#    6) "6379"
#    7) "status"
#    8) "ok"

4.2 触发故障转移

bash
# 1. 模拟主节点宕机
redis-cli -p 6379 DEBUG SLEEP 30  # 主节点休眠 30 秒

# 2. 观察哨兵日志
redis-cli -p 26379 SENTINEL master mymaster | grep -E "flags|ip|port"
# 监控到主节点下线 → 选主 → 切换

# 3. 查看谁是新主节点
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 1) "127.0.0.1"
# 2) "6380"           ← 6380 变成了新主节点

# 4. 验证新主节点可写
redis-cli -p 6380 SET test "sentinel works"
# OK

# 5. 恢复旧主节点
# 等待 30 秒后旧主恢复,自动变成从节点

4.3 查看哨兵状态

bash
# 查看所有哨兵
redis-cli -p 26379 SENTINEL sentinels mymaster
# 1) 1) "name"
#    2) "sentinel1"
#    3) "ip"
#    4) "127.0.0.1"
#    5) "port"
#    6) "26379"

# 查看从节点列表
redis-cli -p 26379 SENTINEL slaves mymaster

# 查看故障转移历史
redis-cli -p 26379 SENTINEL failover-timeout

五、面试视角

追问答案要点
SDOWN 和 ODOWN 的区别?SDOWN 是一个哨兵主观判断;ODOWN 是 quorum 个哨兵确认后触发切换
哨兵如何选主?排除不可用的从节点 → 按优先级 → 按复制偏移 → 按 runid
哨兵脑裂如何缓解?min-slaves-to-write + min-slaves-max-lag 限制分区期间的写入
至少需要几个哨兵?3 个(quorum=2),保证多数派可用。2 个可能平票
哨兵的 Raft 算法用来做什么?选出一个 Leader 哨兵执行故障转移操作
客户端如何知道主节点变更?通过 SENTINEL get-master-addr-by-name 或在 Pub/Sub 订阅 +switch-master 事件
min-slaves-to-write 1 的作用?主节点至少 1 个从节点在线才接受写入,网络分区时旧主无法写入(缓解脑裂)

📚 相关链接

  • **主从复制** — Sentinel 依赖的主从关系
  • **Redis Cluster** — 相比之下 Cluster 的自愈能力
  • ← 返回 **高可用与集群索引**

Knowledge4J — Java 知识库