redis哨兵

Redis 哨兵详解

Redis Sentinel(哨兵)是 Redis 官方提供的高可用性(High Availability, HA)解决方案,用于监控 Redis 主从复制架构,实现自动故障转移(failover)、配置管理和通知。它从 Redis 2.8 开始引入,并在后续版本中不断优化(如 Redis 5.0 提升了选举算法,Redis 7.0+ 优化了网络处理)。Sentinel 本身是一个独立的进程,可以运行在多个节点上,形成分布式监控系统。下面我将详细讲解其机制,包括工作原理、配置方式、例子、优缺点、数据一致性考虑、与主从复制/集群的集成,以及最佳实践。内容基于 Redis 的最新版本(截至 2025 年 9 月 25 日,Redis 8.x),但核心兼容旧版。

1. Redis Sentinel 的概述

Sentinel 是对主从复制的扩展,主要解决主节点单点故障问题。它监控主从节点的心跳,如果主节点宕机,会自动选举一个从节点升级为主,并通知客户端更新配置。

  • 核心功能
    • 监控(Monitoring):定期检查主从节点的健康状态。
    • 故障转移(Failover):主节点故障时,自动切换从节点为主。
    • 配置管理(Configuration Provider):提供主节点地址给客户端,实现透明连接。
    • 通知(Notification):通过脚本或 Pub/Sub 通知管理员故障事件。
  • 适用场景:需要高可用的中小规模 Redis 部署(如缓存、队列),读写分离结合主从。
  • 不适用场景:大规模分片存储(用 Cluster);极高一致性需求(Sentinel 是最终一致性)。
  • 架构:至少 3 个 Sentinel 节点(奇数以多数派选举),分布在不同机器/区域,避免单点。每个 Sentinel 监控同一个主从组(称为 “master-name”)。
  • 优势:简单、零停机 failover(几秒内完成);客户端支持(如 JedisSentinelPool、go-redis 的 Sentinel 模式)。

Sentinel 不存储数据,只管理状态,使用 Raft-like 共识算法选举。

2. 工作原理

Sentinel 的工作分为监控、故障检测、选举和转移四个阶段。

监控阶段
  • 每个 Sentinel 每秒向主从节点发送 PING 命令检查存活。
  • 每 10 秒交换信息(Gossip 协议),共享视图。
  • Sentinel 还监控从节点,收集 replication 状态。
故障检测
  • 主观下线(Subjective Down, SDOWN):单个 Sentinel 如果在 down-after-milliseconds 内未收到 PING 响应,认为节点下线。
  • 客观下线(Objective Down, ODOWN):当多数 Sentinel(quorum)同意主观下线时,确认客观下线,触发 failover。
  • 从节点故障不触发 failover,只监控。
选举与故障转移
  • ODOWN 后,Sentinel 节点通过 Raft 算法选举一个领导者(leader)执行 failover。
  • 领导者选择从节点(基于优先级、offset、runid):发送 REPLICAOF NO ONE 升级从为主;更新其他从的 replicaof;通知旧主(如果恢复)成为从。
  • Failover 时间:通常 5-30 秒,取决于配置。
  • 客户端重连:Sentinel 提供新主地址,客户端需支持 Sentinel 模式重连。
其他机制
  • Pub/Sub:Sentinel 通过 +sdown/+odown 等频道发布事件。
  • 脚本通知:配置 sentinel notification-script 执行 shell 脚本报警。
  • 并行 failover:Redis 4.0+ 支持多 master 组,但每个组独立。
  • 安全性:支持 ACL(Redis 6.0+),Sentinel 可有独立密码。

3. 配置选项

Sentinel 使用独立的配置文件 sentinel.conf,运行命令 redis-sentinel /path/to/sentinel.conf

  • 基本配置

    • port 26379:Sentinel 端口(默认 26379,与 Redis 区分)。
    • sentinel monitor mymaster 127.0.0.1 6379 2:监控主节点(master-name、IP、端口、quorum)。quorum 是 ODOWN 的最小同意数(推荐 (N/2)+1,N 是 Sentinel 数)。
    • sentinel down-after-milliseconds mymaster 30000:下线超时(毫秒,默认 30s)。
    • sentinel failover-timeout mymaster 180000:failover 超时(默认 3min)。
    • sentinel parallel-syncs mymaster 1:failover 后,同时同步从节点的个数(减少负载)。
  • 高级配置

    • sentinel auth-pass mymaster "password":主节点密码。
    • sentinel notification-script mymaster /path/to/script.sh:通知脚本。
    • sentinel client-reconfig-script mymaster /path/to/script.sh:客户端重配置脚本(更新配置中心)。
    • sentinel resolve-hostnames yes:支持主机名(Redis 6.2+)。
    • sentinel announce-ip/announce-port:云环境公告 IP(Redis 6.0+)。
  • 运行时命令(连接 Sentinel CLI:redis-cli -p 26379):

    • SENTINEL masters:列出监控的主组。
    • SENTINEL replicas mymaster:列出从节点。
    • SENTINEL failover mymaster:手动触发 failover。
    • SENTINEL get-master-addr-by-name mymaster:获取当前主地址。
    • INFO sentinel:查看状态。

4. 例子

下面提供实际例子。假设一个主(6379)+两个从(6380、6381)的架构,三个 Sentinel(26379、26380、26381)。使用本地多实例模拟。

示例 1: 配置 Sentinel
  1. 主从配置(如前文主从详解):主 redis.conf 有 requirepass “pass”;从有 replicaof 和 masterauth。

  2. Sentinel 配置(三个类似,端口不同):

    1
    2
    3
    4
    5
    6
    port 26379
    sentinel monitor mymaster 127.0.0.1 6379 2 # quorum=2(3个Sentinel的多数派)
    sentinel down-after-milliseconds mymaster 5000
    sentinel failover-timeout mymaster 60000
    sentinel auth-pass mymaster "pass"
    sentinel parallel-syncs mymaster 1
  3. 启动:

    1
    2
    3
    redis-sentinel /path/to/sentinel1.conf
    redis-sentinel /path/to/sentinel2.conf
    redis-sentinel /path/to/sentinel3.conf
  4. 测试 failover:

    • 连接 Sentinel:redis-cli -p 26379

      1
      SENTINEL get-master-addr-by-name mymaster  # 输出 ["127.0.0.1" "6379"]
    • 杀死主节点进程。

    • Sentinel 日志显示 SDOWN -> ODOWN -> failover。

    • 几秒后,新主选举(假设 6380 升级),查询:

      1
      SENTINEL get-master-addr-by-name mymaster  # 输出 ["127.0.0.1" "6380"]
示例 2: 客户端集成(使用 Go 的 go-redis/v9)

Go 客户端支持 Sentinel 模式,自动发现主节点。

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
28
29
30
31
32
33
34
35
36
37
38
39
package main

import (
"context"
"fmt"
"time"

"github.com/redis/go-redis/v9"
)

func main() {
ctx := context.Background()
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster", // Sentinel 中的 master-name
SentinelAddrs: []string{"127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381"},
Password: "pass",
DB: 0,
DialTimeout: 5 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
})

// 测试写操作(自动连接当前主)
err := client.Set(ctx, "key", "value", 0).Err()
if err != nil {
fmt.Println("Set error:", err)
return
}

// 测试读操作
val, err := client.Get(ctx, "key").Result()
if err != nil {
fmt.Println("Get error:", err)
} else {
fmt.Println("Value:", val) // 输出: Value: value
}

// 模拟 failover 后,客户端自动重连新主
}
  • 客户端会查询 Sentinel 获取主地址,支持读从(用 ReadOnly 选项)。
示例 3: 通知脚本

在 sentinel.conf 添加:

1
sentinel notification-script mymaster /path/to/notify.sh

notify.sh 示例:

1
2
3
4
#!/bin/bash
event_type=$1
# 发送邮件或 Slack 通知
echo "Sentinel event: $event_type" | mail -s "Redis Alert" admin@example.com

5. 优点

  • 自动 HA:无人工干预 failover,downtime 最小。
  • 分布式:多 Sentinel 避免单点,Gossip 确保一致视图。
  • 易集成:客户端库支持透明连接。
  • 轻量:无额外存储开销,资源消耗低。
  • 可扩展:支持多 master 组(Redis 4.0+)。

6. 缺点与局限性

  • 不分片:所有数据在单一主,不适合大数据(用 Cluster)。
  • 一致性弱:failover 可能丢失最近写(取决于 replication lag)。
  • 选举开销:网络分区可能导致脑裂(split-brain),虽罕见。
  • 配置复杂:需手动设置多个 Sentinel 和脚本。
  • 不适合写密集:所有写仍集中主。
  • 版本依赖:旧版(如 2.8)选举慢,推荐 6.0+。

7. 与主从复制和集群的比较

  • 主从复制:基础,Sentinel 构建在其上,提供手动 failover 的自动化。
  • Cluster:内置 HA 和分片,适合大规模(16384 槽),但更复杂、无 Sentinel 的配置管理。Cluster 有内置 Sentinel-like 机制。
  • 选择:简单 HA 用 Sentinel;分布式用 Cluster;混合用 Cluster + Sentinel(少用)。

8. 数据一致性与恢复

  • 一致性:异步复制 + failover,可能有几秒 lag。用 min-replicas-to-write 在主配置加强。
  • 恢复:旧主恢复后自动成为从。监控 lag 用 SENTINEL replicas。
  • 持久化集成:主从都启用 AOF,确保 failover 后数据恢复。

9. 最佳实践

  • 奇数 Sentinel:至少 3 个,分布不同 AZ/机器,quorum = (N/2)+1。
  • 网络优化:专用网络,设置 down-after-milliseconds 适中(避免误判)。
  • 客户端:用 Sentinel 模式库,避免硬编码 IP。
  • 监控:用 Prometheus + Redis Exporter 监控 Sentinel 指标(failover 次数、lag)。
  • 测试:定期模拟故障(kill 主),验证 failover 和客户端重连。
  • 安全:设置 Sentinel auth-sentinel-pass(Redis 7.0+);用 TLS 加密。
  • 避免坑:不要在 Sentinel 节点跑 Redis 实例;大数据用 diskless replication;升级到 8.x 以获稳定性提升。
  • 扩展:多 master 组时,每个组独立 Sentinel 配置。
[up主专用,视频内嵌代码贴在这]