哨兵模式的作用

哨兵模式的作用

一句话回答

Redis Sentinel(哨兵)是一个分布式监控系统,负责监控主从状态自动故障转移(主节点挂了自动选新主)和通知客户端新主节点地址,实现高可用。


哨兵的核心功能

功能 说明
监控(Monitoring) 持续检查主节点和从节点是否正常运行
通知(Notification) 通过 API 通知管理员或其他系统节点状态变化
自动故障转移(Automatic Failover) 主节点不可用时,选举一个从节点升级为新主
配置提供(Configuration Provider) 客户端连接哨兵查询当前主节点地址

为什么需要哨兵?

没有哨兵的脆弱性

主机宕机 → 手动切换 → 业务停服 N 分钟
     │                    │
     │                    └── 手工执行 SLAVEOF NO ONE
     │                        手工修改所有客户端连接地址
     ▼
    业务中断!

有哨兵的高可用

主节点宕机
    │
    ▼
哨兵集群(3+ 个哨兵实例)
    │
    ├── 检测主节点主观下线(S_DOWN)
    ├── 多个哨兵确认客观下线(O_DOWN) → 开始故障转移
    │
    ├── 选一个从节点升为主 → SLAVEOF NO ONE
    ├── 其他从节点改为复制新主
    │
    ▼
客户端 → 查询哨兵 → 获取新主地址 → 继续服务
        总耗时 ≈ 10-30 秒

配置示例

# sentinel.conf

# 监听主节点(名为 mymaster,IP:port,至少 2 个哨兵同意才认为挂了)
sentinel monitor mymaster 127.0.0.1 6379 2

# 认证密码
sentinel auth-pass mymaster yourpassword

# 主观下线判定时间(30 秒无响应就认为挂了)
sentinel down-after-milliseconds mymaster 30000

# 故障转移超时(3 分钟)
sentinel failover-timeout mymaster 180000

# 同时向新主同步的从节点数(1 = 串行)
sentinel parallel-syncs mymaster 1

启动哨兵

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

故障转移过程详解

时间线:

T+0s     主节点宕机
T+0~30s  哨兵 A 发现主节点无响应  S_DOWN(主观下线)
T+0~30s  哨兵 BC 也发现主节点无响应  S_DOWN
T+30s    至少 2 个哨兵都认为主节点挂了  O_DOWN(客观下线)
T+30s    选举 leader 哨兵(Raft 算法)
T+30.1s  Leader 哨兵执行故障转移:

Step 1: 从从节点中选一个新主
        筛选条件:复制偏移最大、配置纪元最新、RUNID 最小
Step 2: 向选中的从节点发送 SLAVEOF NO ONE
Step 3: 等待从节点确认升主完成
Step 4: 向其他从节点发送 SLAVEOF {新主 IP} {新主端口}
Step 5: 修改自身配置,记录新主节点信息

T+32s    故障转移完成
T+32s    客户端重新查询哨兵获取新主地址  业务恢复

总耗时:通常 10-30 秒,取决于 down-after-milliseconds 的设置。


哨兵的分布式共识

哨兵至少需要 3 个实例

sentinel monitor mymaster 127.0.0.1 6379 2
# quorum = 2 → 至少 2 个哨兵都认为挂了才算

部署建议

哨兵数量 可容忍挂掉数量 推荐场景
1 0(单点故障) ❌ 不推荐
2 0(不满足 quorum 时脑裂) ❌ 不推荐
3 1 ✅ 最小推荐
5 2 ✅ 生产环境
7 3 超大规格

为什么 2 个不够:假设主节点挂了,哨兵 A 认为自己没挂,哨兵 B 认为挂了(网络分区)。quorum=2 需要两个都同意,但网络分区下无法达成一致→不会触发故障转移。


哨兵与客户端交互

客户端发现主节点

import redis
from redis.sentinel import Sentinel

sentinel = Sentinel([('localhost', 26379)], 
                     socket_timeout=0.1)

# 获取当前主节点(自动发现,即使故障转移后)
master = sentinel.master_for('mymaster', 
                             socket_timeout=0.1,
                             redis_class=redis.StrictRedis)

# 获取从节点(读操作)
slave = sentinel.slave_for('mymaster', 
                            socket_timeout=0.1,
                            redis_class=redis.StrictRedis)

当发生故障转移时:

客户端  查询哨兵sentinel get-master-addr-by-name mymaster
         获取新主节点 IP:port
         自动重建连接
         业务无感

面试考点

Q1:哨兵怎么判断主节点真的挂了?

两次判定:

  1. 主观下线(S_DOWN):单个哨兵发现 down-after-milliseconds 时间没收到 PONG
  2. 客观下线(O_DOWN):quorum 个哨兵确认主节点处于 S_DOWN 状态

Q2:哨兵之间怎么通信?

哨兵通过 Redis 的 pub/sub 机制交换信息(__sentinel__:hello 频道),也通过超时和 Raft 协议选举 leader。

Q3:故障转移期间 Redis 能读吗?

  • 从节点可以读(但数据不写也不完整,因为主节点宕机)
  • 如果 replica-serve-stale-data yes,从节点可读旧数据
  • 写操作全都会失败,直到新主节点选举完成

Q4:主节点恢复后怎么处理?

旧主节点恢复后,哨兵会发现它并重新配置为从节点SLAVEOF 新主)。数据通过全量复制从新主同步。


总结:哨兵模式让 Redis 从「手动运维」升级为「自动高可用」。三个哨兵实例形成最小高可用部署单元,10-30 秒的切换时间适用于绝大多数业务场景。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容