Redis哨兵模式详解

Redis哨兵模式(Sentinel)详解

一、哨兵模式简介

什么是哨兵模式

哨兵(Sentinel)是一种分布式系统 ,用于监控主从架构中每个节点的运行状态。当主节点(Master)出现故障时,哨兵通过投票机制自动选举新的主节点,并将从节点(Slave)切换到新的主节点,从而实现Redis集群的自动故障转移

哨兵模式能解决什么问题

在主从复制架构中,如果主节点宕机:

  • 从节点无法自动升级为主节点
  • 写入操作无法进行
  • 服务彻底不可用

哨兵模式就是为了解决这些问题而设计的,它能自动监测、自动转移、自动通知,确保Redis服务的高可用性。

哨兵模式架构图

复制代码
                        ┌─────────────────┐
                        │     哨兵节点      │
                        │   (Sentinel)     │
                        └────────┬─────────┘
                                 │ PING/PONG (监控)
        ┌────────────────────────┼────────────────────────┐
        │                        │                        │
        ▼                        ▼                        ▼
┌───────────┐  异步复制   ┌───────────┐  异步复制   ┌───────────┐
│  主节点   │───────────►│  从节点1  │───────────►│  从节点2  │
│  Master   │            │  Slave1   │            │  Slave2   │
└───────────┘            └───────────┘            └───────────┘

架构说明

  • Sentinel → Redis节点:单向发送PING,接收PONG(监控)
  • Master → Slave:单向异步复制(数据同步)
  • Slave → Master:单向发送ACK确认(复制确认)

二、哨兵模式核心功能

1. 持续监控

哨兵会持续监控主节点和从节点的运行状态,包括:

  • 主节点是否可达
  • 从节点是否正常复制
  • 网络连接是否稳定

2. 自动故障转移

当主节点不可用时,哨兵会自动:

  1. 检测并确认主节点故障(SDOWN → ODOWN)
  2. 通过Raft算法选举leader哨兵
  3. 选择一个从节点升级为新的主节点
  4. 将其他从节点指向新的主节点
  5. 通知客户端更新主节点地址

3. 通知机制

故障转移完成后,哨兵支持:

  • 通过API通知运维人员
  • 发送告警邮件/短信
  • 执行自定义脚本(如重启服务、发送通知)

三、故障转移详细流程

1. 主观下线检测

复制代码
客户端 ──PING──► Redis节点
         ◄──PONG──
  • 哨兵每10秒向Redis节点发送PING命令
  • 如果节点超过down-after-milliseconds(默认30秒)未响应,哨兵认为该节点主观下线(SDOWN)

2. 客观下线确认

  • 多个哨兵节点同时检测到主节点下线
  • 达到quorum配置的数量后,确认客观下线(ODOWN)
  • 例如:3个哨兵,quorum=2,表示至少2个哨兵认为主节点下线才触发转移

3. 选举Leader哨兵

  • 哨兵集群通过Raft算法进行Leader选举
  • 只有Leader哨兵才能执行故障转移
  • 选举依据:先到先得,优先级高的更容易当选

4. 选择新主节点

Leader哨兵从从节点列表中选择新主节点,选择规则:

  1. 优先级高的(replica-priority配置)
  2. 复制偏移量大的(数据最新)
  3. 运行ID小的(启动时间早)

5. 执行转移

bash 复制代码
# 原主节点故障后,哨兵执行以下操作:
1. SLAVEOF NO ONE   # 让选中的从节点取消从属关系,成为主节点
2. 向其他从节点发送SLAVEOF命令  # 让它们指向新的主节点
3. 更新配置文件  # 记录新的主节点信息

6. 通知客户端

bash 复制代码
# 哨兵通过发布/订阅机制通知客户端
PUBLISH +switch-master mymaster 192.168.72.11 6379 192.168.72.12 6379
# 格式:新主节点IP 新主节点端口 旧主节点IP 旧主节点端口

四、哨兵配置详解

典型配置文件

conf 复制代码
# 创建配置目录
mkdir -p /usr/local/redis/sentinel

# 哨兵端口
port 26379

# 守护进程模式
daemonize yes

# PID文件
pidfile /usr/local/redis/redis-sentinel-26379.pid

# 日志文件
logfile "/usr/local/redis/sentinel_26379.log"

# 工作目录
dir /usr/local/redis/sentinel

# 监控主节点配置
# sentinel monitor <master-name> <ip> <port> <quorum>
sentinel monitor mymaster 192.168.72.11 6379 2

# 主节点不可达超时时间(毫秒)
sentinel down-after-milliseconds mymaster 5000

# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 60000

# 主节点认证密码
sentinel auth-pass mymaster 1234

# 哨兵节点间通信密码(可选)
requirepass "12345"

核心配置项说明

配置项 说明 推荐值
sentinel monitor 监控的主节点名称、IP、端口、quorum quorum=节点数/2+1
sentinel down-after-ms 主观下线超时时间 5000ms(5秒)
sentinel failover-timeout 故障转移超时时间 60000ms(1分钟)
sentinel auth-pass 主节点密码 与redis.conf一致
sentinel parallel-syncs 同时同步的从节点数量 1

quorum配置建议

  • 3个哨兵节点:quorum设为2
  • 5个哨兵节点:quorum设为3
  • 原则:quorum > 哨兵节点总数/2

五、常用运维命令

查看集群状态

bash 复制代码
# 查看哨兵整体信息
redis-cli -p 26379 info sentinel

# 查看监控的主节点列表
redis-cli -p 26379 sentinel masters

# 查看指定主节点详细信息
redis-cli -p 26379 sentinel master mymaster

# 查看从节点信息
redis-cli -p 26379 sentinel slaves mymaster

# 查看所有哨兵节点
redis-cli -p 26379 sentinel sentinels mymaster

# 查询当前主节点地址
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster

手动故障转移

bash 复制代码
# 手动触发故障转移(谨慎使用)
redis-cli -p 26379 sentinel failover mymaster

完整验证示例

bash 复制代码
# 1. 查看当前主节点
[root@centos ~]# redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
1) "192.168.72.11"
2) "6379"

# 2. 模拟主节点故障
[root@centos ~]# kill <主节点进程ID>

# 3. 查看故障转移日志,可以看到新主节点变为192.168.72.12
# 4. 再次查询主节点地址
[root@centos ~]# redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
1) "192.168.72.12"
2) "6379"

六、客户端如何连接哨兵

工作原理

客户端不直接连接固定的主节点,而是通过哨兵获取主节点地址:

复制代码
1. 客户端连接哨兵节点列表(预配置)
2. 客户端查询哨兵获取当前主节点地址
3. 客户端直接连接主节点进行读写
4. 哨兵检测到主节点变更,发布通知
5. 客户端刷新主节点地址缓存
6. 下次请求自动路由到新主节点

客户端代码示例(Jedis)

java 复制代码
// Jedis 2.x/3.x 连接哨兵示例
Set<String> sentinelIPs = new HashSet<>();
sentinelIPs.add("192.168.72.11:26379");
sentinelIPs.add("192.168.72.12:26379");
sentinelIPs.add("192.168.72.13:26379");

// masterName必须与sentinel.conf中的一致,password是Redis密码
JedisSentinelPool pool = new JedisSentinelPool(
    "mymaster",        // 与sentinel monitor配置的名称一致
    sentinelIPs,        // 哨兵节点列表
    "1234"             // Redis密码(与requirepass一致)
);

// 获取连接后即可使用
Jedis jedis = pool.getResource();
jedis.set("key", "value");
String value = jedis.get("key");

// 关闭连接(不是关闭pool)
jedis.close();

关键点

  1. mymaster 必须与哨兵配置中的名称一致
  2. 密码必须与主节点 requirepass 一致
  3. JedisSentinelPool 内部自动订阅哨兵频道,自动刷新主节点地址

为什么客户端必须通过哨兵

  1. 主节点地址会动态变化:故障转移后主节点IP/端口会改变,客户端无法预知
  2. 主从切换对客户端透明:客户端只需连接哨兵,由哨兵提供当前主节点地址

七、哨兵模式优缺点

优点

  1. 高可用保障:自动检测、自动转移,无需人工干预
  2. 自动选主:从节点自动升级,无需手动配置
  3. 写分离支持:主节点处理写,从节点处理读,分担压力
  4. 地址通知:自动通知客户端主节点变化,无需修改客户端配置
  5. 告警机制:支持通过API和脚本通知运维人员

缺点

  1. 维护成本较高:至少需要3个哨兵节点,增加部署复杂度
  2. 故障转移期间有数据丢失风险:异步复制可能导致部分数据丢失
  3. 客户端需要支持哨兵:老版本客户端可能不支持

八、与主从复制的区别

对比项 主从复制 哨兵模式
核心功能 数据同步 高可用 + 数据同步
故障转移 手动 自动
主节点选举 手动操作 自动选举
客户端配置 固定主节点地址 连接哨兵获取地址
运维复杂度
适用场景 数据备份、读写分离 高可用集群

九、面试常见问题

Q1:哨兵模式是如何发现主节点故障的?

答:哨兵通过发送PING命令监测节点响应,如果超过down-after-milliseconds时间未收到响应,标记为主观下线(SDOWN)。当足够多的哨兵(达到quorum)都认为主节点下线时,确认为客观下线(ODOWN)。

Q2:quorum配置为2时,3个哨兵能否完成故障转移?

答:可以。quorum=2表示至少2个哨兵认为主节点下线即可触发故障转移。但实际执行转移的只有被选中的Leader哨兵。

Q3:为什么哨兵至少需要3个节点?

答:3个哨兵可以通过多数投票避免脑裂(split-brain)问题。如果只有2个哨兵,一个哨兵认为主节点下线,另一个认为在线,可能导致数据不一致。

Q4:故障转移期间数据会丢失吗?

答:有可能。因为主从复制是异步的,主节点故障前接收到的部分写操作可能尚未同步到从节点,这些数据会丢失。这是CAP定理中选择AP(可用性+分区容错)的代价。

Q5:客户端如何知道主节点变更了?

答:客户端订阅哨兵的+switch-master频道,故障转移完成后哨兵会发布新的主节点地址,客户端收到通知后自动更新连接地址。

相关推荐
重生之小比特1 小时前
【MySQL 数据库】复合查询
android·数据库·mysql
夕除1 小时前
spring boot --07
数据库·sql
Elastic 中国社区官方博客1 小时前
Elasticsearch:为 AI Agent builder 创建 skill plugin
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
Data_Journal1 小时前
2026年十大数据集网站
大数据·开发语言·数据库·人工智能·python
珠海西格电力1 小时前
如何实现零碳园区管理系统“云-边-端”架构的协同
大数据·数据库·人工智能·架构·能源
XS0301061 小时前
JDBC实现数据库增删改查
数据库
茉莉玫瑰花茶1 小时前
LangGraph 入门教程:构建 AI 工作流 [ 案例一 ]
数据库
宸凉1 小时前
Oracle 19C的安装
数据库·oracle
YL200404262 小时前
MySQL-基础篇-约束
数据库·mysql