导言

哨兵模式(Sentinel)是 Redis 主从复制架构的 “高可用增强层”,通过分布式共识机制解决了主从复制中 “主节点宕机需手动切换” 的痛点,实现故障自动检测、主节点自动选举、从节点自动同步,是中小规模 Redis 集群(数据量 < 10GB、读多写少)的生产级高可用标准方案。

一、哨兵模式的核心定位与价值

1.1 在理解哨兵前,需先明确其与主从复制的关系:

主从复制负责 “数据同步”(主写从读、数据备份),但无法自动处理主节点故障;

哨兵负责 “高可用保障”(监控、故障转移、配置自动更新),是主从架构的 “大脑”,二者协同实现 99.99% 服务可用性。

1.2 哨兵模式的核心价值

  1. 彻底告别手动运维:主节点宕机后,无需人工干预,10-30 秒内完成故障转移

  2. 分布式容错:多哨兵节点共识判断,避免单点误判(如网络抖动导致的假宕机)

  3. 客户端透明路由:客户端可通过哨兵获取当前主节点地址,无需硬编码 IP / 端口

  4. 配置动态同步:故障转移后,自动通知所有从节点切换新主节点,更新同步关系

二、哨兵的核心功能与工作原理

2.1 四大核心功能拆解

功能模块 具体实现逻辑
主从节点监控 每个哨兵每秒向主节点、从节点、其他哨兵发送PING 命令,检测节点存活状态
节点状态通知 哨兵通过发布订阅(Pub/Sub) 机制(频道__sentinel__:hello)传播节点状态,保持信息同步
故障检测 区分 “主观下线(SDOWN)” 和 “客观下线(ODOWN)”,避免单点误判
自动故障转移 主节点客观下线后,选举哨兵 leader 执行故障转移,包括新主节点选举、从节点同步等

2.2 关键机制:主观下线(SDOWN)与客观下线(ODOWN)

这是哨兵避免 “误判宕机” 的核心设计,必须严格区分:

(1)主观下线(Subjective Down)

  • 定义:单个哨兵在down-after-milliseconds时间内(默认 30 秒),未收到目标节点的有效响应(PONG/LOADING/MASTERDOWN),则认为该节点 “主观下线”

  • 特点:仅单个哨兵的判断,可能因网络抖动、节点临时阻塞导致误判

  • 配置关联:sentinel down-after-milliseconds mymaster 30000(30 秒无响应触发 SDOWN)

(2)客观下线(Objective Down)

  • 定义:当哨兵判断主节点主观下线后,会向其他哨兵发送SENTINEL is-master-down-by-addr命令,询问是否同意该主节点下线;若超过 quorum(法定票数) 的哨兵同意,则标记主节点 “客观下线”

  • 特点:分布式共识判断,避免单点误判,是触发故障转移的前提

  • 配置关联:sentinel monitor mymaster 192.168.1.100 6379 2(quorum=2,需 2 个哨兵同意触发 ODOWN)

注意:仅主节点会触发 “客观下线” 流程,从节点 / 哨兵节点主观下线后,直接标记为宕机,无需共识判断。

三、哨兵模式的部署架构与配置最佳实践

3.1 部署架构原则(生产环境必遵循)

  • 奇数哨兵节点:推荐 3/5 个(避免 “脑裂”,如 3 个哨兵需 2 票同意,5 个需 3 票,确保唯一 leader)

  • 物理隔离:哨兵节点与主从节点分开部署(如主从在机房 A,哨兵 1 在机房 A,哨兵 2/3 在机房 B,避免机房断电导致全宕机)

  • 网络互通:所有哨兵节点需能访问主从节点(端口 6379/6380),哨兵之间需互通(默认端口 26379)

  • 配置一致:所有哨兵的monitor参数、down-after-milliseconds、failover-timeout需保持一致,避免判断逻辑混乱

3.2 核心配置详解(sentinel.conf)

基于 Redis 7.0,重点解读生产环境需调整的参数,避免默认配置坑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 1. 基础网络配置
port 26379 # 哨兵端口(默认26379,多哨兵需不同端口)
bind 0.0.0.0 # 生产环境指定内网IP,避免公网访问
protected-mode yes # 开启保护模式,需密码/IP白名单才能访问

# 2. 主节点监控配置(核心)
sentinel monitor mymaster 192.168.1.100 6379 2
# 格式:sentinel monitor <主节点名称> <主节点IP> <主节点端口> <quorum票数>
# 说明:mymaster是自定义名称,quorum=2表示需2个哨兵同意才触发ODOWN

# 3. 安全配置(必配,避免未授权访问)
sentinel auth-pass mymaster Redis@2025
# 主节点的密码(与主节点requirepass一致,否则无法监控)
sentinel requirepass Sentinel@2025
# 哨兵节点之间的通信密码(避免恶意哨兵接入)

# 4. 故障检测配置
sentinel down-after-milliseconds mymaster 30000
# 触发SDOWN的时间(30秒,跨机房建议调至50000-60000ms,应对网络延迟)
sentinel parallel-syncs mymaster 1
# 故障转移时,同时同步新主节点的从节点数量(1=串行同步,避免新主节点负载过高)

# 5. 故障转移超时配置
sentinel failover-timeout mymaster 180000
# 故障转移总超时时间(180秒,超时则重新发起故障转移)
sentinel deny-scripts-reconfig yes
# 禁止动态修改脚本配置(安全防护,避免恶意脚本注入)

3.3 部署步骤(基于 3 哨兵 + 1 主 2 从架构)

步骤 1:准备环境(延续主从架构)

步骤 2:配置 3 个哨兵节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 哨兵1配置(192.168.1.103)
cat > /etc/redis/sentinel1.conf << EOF
port 26379
bind 192.168.1.103
protected-mode yes
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel auth-pass mymaster Redis@2025
sentinel requirepass Sentinel@2025
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
EOF

# 哨兵2/3配置:仅修改port和bind(如哨兵2端口26380、IP192.168.1.104)

步骤 3:启动哨兵并验证

1
2
3
4
5
6
7
8
9
10
11
12
13
# 启动3个哨兵(后台启动需加--daemonize yes)
redis-sentinel /etc/redis/sentinel1.conf
redis-sentinel /etc/redis/sentinel2.conf
redis-sentinel /etc/redis/sentinel3.conf

# 验证哨兵状态(连接任意哨兵,需输入哨兵密码)
redis-cli -h 192.168.1.103 -p 26379 -a Sentinel@2025 info sentinel

# 关键输出(表示监控正常):
# sentinel_masters:1
# sentinel_monitored_slaves:2 # 2个从节点已被监控
# sentinel_leader:192.168.1.103:26379 # 已选举出哨兵leader
# sentinel_tilt:0 # 0=正常,1=哨兵处于倾斜状态(需排查)

四、故障转移实战:模拟主节点宕机

通过实操理解哨兵如何自动恢复服务,步骤如下:

4.1 模拟主节点宕机

1
2
# 连接主节点并关闭(192.168.1.100:6379)
redis-cli -h 192.168.1.100 -p 6379 -a Redis@2025 shutdown

4.2 观察哨兵日志(关键节点)

查看任意哨兵的日志(如哨兵 1 的日志/var/log/redis/sentinel1.log),核心日志片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 标记主节点SDOWN
1088:X 08 Sep 2025 10:00:00.123 # +sdown master mymaster 192.168.1.100 6379
# 2. 发起投票,达成共识后标记ODOWN
1088:X 08 Sep 2025 10:00:01.456 # +odown master mymaster 192.168.1.100 6379 #quorum 2/2
# 3. 选举哨兵leader(此处哨兵1当选)
1088:X 08 Sep 2025 10:00:02.789 # +leader 192.168.1.103:26379 master mymaster 192.168.1.100 6379
# 4. 筛选从节点(假设192.168.1.101:6380优先级最高)
1088:X 08 Sep 2025 10:00:03.234 # +selected-slave slave 192.168.1.101:6380 192.168.1.101 6380 @ mymaster 192.168.1.100 6379
# 5. 将从节点晋升为主节点
1088:X 08 Sep 2025 10:00:03.567 # +promoted-slave slave 192.168.1.101:6380 192.168.1.101 6380 @ mymaster 192.168.1.100 6379
# 6. 通知其他从节点(192.168.1.102:6381)切换主节点
1088:X 08 Sep 2025 10:00:05.890 # +slave-reconf-sent slave 192.168.1.102:6381 192.168.1.102 6381 @ mymaster 192.168.1.100 6379
# 7. 故障转移完成,新主节点生效
1088:X 08 Sep 2025 10:00:08.123 # +failover-end master mymaster 192.168.1.100 6379
# 8. 更新主节点地址(新主节点为192.168.1.101:6380)
1088:X 08 Sep 2025 10:00:08.456 # +switch-master mymaster 192.168.1.100 6379 192.168.1.101 6380

4.3 验证故障转移结果

1
2
3
4
5
6
7
8
9
10
11
# 1. 查看新主节点状态(192.168.1.101:6380)
redis-cli -h 192.168.1.101 -p 6380 -a Redis@2025 info replication
# 关键输出:role:master, connected_slaves:1(192.168.1.102:6381已同步)

# 2. 通过哨兵获取当前主节点地址(客户端常用方式)
redis-cli -h 192.168.1.103 -p 26379 -a Sentinel@2025 sentinel get-master-addr-by-name mymaster
# 输出:1) "192.168.1.101" 2) "6380"(正确返回新主节点)

# 3. 恢复原主节点(192.168.1.100:6379)
redis-server /etc/redis/redis-master.conf
# 验证:原主节点会自动成为新主节点的从节点(role:slave,master_host:192.168.1.101)

五、哨兵模式的适用场景与局限性

5.1 适用场景

  • 中小规模 Redis 集群:数据量 < 10GB,读写分离需求明确(如电商商品详情页、用户会话存储)

  • 对运维成本敏感:无需复杂的分片管理(对比 Redis Cluster),配置简单

  • 高可用优先级高于扩展性:需自动故障转移,但无需横向扩展写性能(主从架构写性能依赖单主节点)

5.2 局限性(需注意)

  • 写性能瓶颈:所有写请求集中在主节点,无法通过加节点扩展写性能(Redis Cluster 可解决)

  • 数据一致性风险:主从复制存在异步延迟(毫秒级),极端情况下可能丢失数据(需结合min-replicas-to-write优化)

  • 不支持分片:所有节点存储全量数据,数据量过大(>10GB)时,从节点加载 RDB 缓慢,复制延迟升高