04.2 - 哨兵 Sentinel 机制
定位: Redis 的高可用守护进程——自动监控、自动故障转移、统一配置 面试高频度: ⭐⭐⭐⭐ 考查方式: 哨兵核心功能、主观下线 vs 客观下线、Raft 选主、脑裂问题
一、这是什么?为什么需要它?
是什么
Sentinel(哨兵)是一个分布式监控系统,对 Redis 主从集群进行监控、通知和自动故障转移。
为什么需要 Sentinel?
只有主从复制的问题:
- 主节点宕机:人工介入 → 选一个从节点 → 手动 SLAVEOF NO ONE → 其他从节点指向新主节点 → 通知客户端更新连接。整个过程 5-30 分钟的运维操作
- 无人值守的噩梦:半夜 3 点主节点挂了,在线业务全部写失败
Sentinel 的解决:
- 自动故障转移 → 30 秒内完成切换
- 通知客户端 → 通过 Pub/Sub 广播新主配置
- 哨兵本身高可用 → 至少 3 个哨兵实例
- 配置中心 → 客户端从哨兵获取主节点地址
二、原理拆解
2.1 哨兵架构
2.2 监控机制
Sentinel 的三种监控:
- 与主节点通信(每 10 秒 INFO + PING)→ 获取主从拓扑信息、发现新的从节点、检查主节点状态
- 与从节点通信(每 10 秒 INFO + PING)→ 获取从节点复制偏移量、检查从节点是否存活
- 哨兵间通信(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 的自愈能力
- ← 返回 **高可用与集群索引**