从入门到精通【Redis】初识Redis哨兵机制(Sentinel)

文章目录

    • [📕1. 相关名词解释](#📕1. 相关名词解释)
    • [📕2. 对比人工恢复与哨兵恢复主节点的过程](#📕2. 对比人工恢复与哨兵恢复主节点的过程)
        • [✏️2.1 ⼈⼯恢复主节点过程](#✏️2.1 ⼈⼯恢复主节点过程)
        • [✏️2.2 哨兵恢复主节点过程](#✏️2.2 哨兵恢复主节点过程)
    • [📕3. 基于Docker快速安装部署](#📕3. 基于Docker快速安装部署)
        • [✏️3.1 准备工作](#✏️3.1 准备工作)
        • [✏️3.2 编排 redis 主从节点](#✏️3.2 编排 redis 主从节点)
        • [✏️3.3 编排 redis-sentinel 节点](#✏️3.3 编排 redis-sentinel 节点)
    • [📕4. 选举原理](#📕4. 选举原理)

特此注明 :
Designed By :长安城没有风
Version:1.0
Time:2025.10.09
Location:辽宁 · 大连

Redis 的主从复制模式下,⼀旦主节点由于故障不能提供服务,需要⼈⼯进⾏主从切换,同时⼤量的客户端需要被通知切换到新的主节点上,对于上了⼀定规模的应⽤来说,这种⽅案是⽆法接受的,于是 Redis 从 2.8 开始提供了 Redis Sentinel(哨兵)方案来解决这个问题。本篇文章会给大家简单介绍一下Redis Sentinel方案

📕1. 相关名词解释

Redis Sentinel 是 Redis 的⾼可⽤实现⽅案,在实际的⽣产环境中,对提⾼整个系统的⾼可⽤是⾮常有帮助的,由于对 Redis 的许多概念都有不同的名词解释,所以在介绍 Redis Sentinel 之前,先对⼏个名词概念进⾏必要的说明。

名词 逻辑结构 物理结构
主节点 Redis 主服务 ⼀个独⽴的 redis-server 进程
从节点 Redis从服务 ⼀个独⽴的 redis-server 进程
Redis 数据节点 主从节点 主节点和从节点的进程
哨兵节点 监控 Redis 数据节点的节点 ⼀个独⽴的 redis-sentinel 进程
哨兵节点集合 若⼲哨兵节点的抽象组合 若⼲ redis-sentinel 进程
Redis 哨兵(Sentinel) Redis 提供的⾼可⽤⽅案 哨兵节点集合 和 Redis 主从节点
应⽤⽅ 泛指⼀个或多个客户端 ⼀个或多个连接 Redis 的进程

📕2. 对比人工恢复与哨兵恢复主节点的过程

✏️2.1 ⼈⼯恢复主节点过程

1. 运维⼈员通过监控系统,发现 Redis 主节点故障宕机


2. 运维⼈员从所有节点中,选择⼀个(此处选择了 slave 1)执⾏ slaveof no one,使其作为新的主节点。


3. 运维⼈员让剩余从节点(此处为 slave 2)执⾏ slaveof {newMasterIp} {newMasterPort} 从新主节点开始数据同步。

4. 更新应⽤⽅连接的主节点信息到 {newMasterIp} {newMasterPort}。

5. 如果原来的主节点恢复,执⾏ slaveof {newMasterIp} {newMasterPort} 让其成为⼀个从节点。

✏️2.2 哨兵恢复主节点过程

Redis Sentinel 架构


Redis Sentinel 相⽐于主从复制模式是多了若⼲(建议保持奇数)Sentinel 节点⽤于实现监控数据节点,哨兵节点会定期监控所有节点(包含数据节点和其他哨兵节点)。针对主节点故障的情况,故障转移流程⼤致如下:

  1. 主节点故障,从节点同步连接中断,主从复制停⽌。
  2. 哨兵节点通过定期监控发现主节点出现故障。哨兵节点与其他哨兵节点进⾏协商,达成多数认同主节点故障的共识。(这步主要是防⽌该情况:出故障的不是主节点,⽽是发现故障的哨兵节点,该情况经常发⽣于哨兵节点的⽹络被孤⽴的场景下)
  3. 哨兵节点之间使⽤ Raft 算法选举出⼀个领导⻆⾊,由该节点负责后续的故障转移⼯作。
  4. 哨兵领导者开始执⾏故障转移:从节点中选择⼀个作为新主节点;让其他从节点同步新主节点;通知应⽤层转移到新主节点。


通过上⾯的介绍,可以看出 Redis Sentinel 具有以下⼏个功能:

  1. 监控: Sentinel 节点会定期检测 Redis 数据节点、其余哨兵节点是否可达。
  2. 故障转移: 实现从节点晋升(promotion)为主节点并维护后续正确的主从关系。
  3. 通知: Sentinel 节点会将故障转移的结果通知给应⽤⽅。

📕3. 基于Docker快速安装部署

✏️3.1 准备工作

1. 安装 docker 和 docker-compose

2. 停⽌之前的 redis-server

复制代码
# 停⽌ redis-server
service redis-server stop

3. 使⽤ docker 获取 redis 镜像

复制代码
docker pull redis:5.0.9
✏️3.2 编排 redis 主从节点

1. 编写 docker-compose.yml

创建 /root/redis/docker-compose.yml , 同时 cd 到 yml 所在⽬录中。

注意 : docker 中可以通过容器名字, 作为 ip 地址, 进⾏相互之间的访问。

bash 复制代码
version: '3.7'
services:

	master:
		image: 'redis:5.0.9'
		container_name: redis-master
		restart: always
		command: redis-server --appendonly yes
		ports: 
			- 6379:6379
			- 
	slave1:
		image: 'redis:5.0.9'
		container_name: redis-slave1
		restart: always
		command: redis-server --appendonly yes --slaveof redis-master 6379
		ports:
			- 6380:6379
			- 
	slave2:
		image: 'redis:5.0.9'
		container_name: redis-slave2
		restart: always
		command: redis-server --appendonly yes --slaveof redis-master 6379
		ports:
			- 6381:6379

2. 启动所有容器

bash 复制代码
docker-compose up -d

如果启动后发现前⾯的配置有误,需要重新操作,使⽤ docker-compose down 即可停⽌并删除刚才创建好的容器。

3. 查看运⾏⽇志

bash 复制代码
docker-compose logs

上述操作必须保证⼯作⽬录在 yml 的同级⽬录中,才能⼯作。

✏️3.3 编排 redis-sentinel 节点

也可以把 redis-sentinel 放到和上⾯的 redis 的同⼀个 yml 中进⾏容器编排,此处分成两组,主要是为了两⽅⾯:

  1. 观察⽇志⽅便
  2. 确保 redis 主从节点启动之后才启动 redis-sentinel,如果先启动 redis-sentinel 的话,可能触发额外的选举过程,混淆视听。(不是说先启动哨兵不⾏,⽽是观察的结果可能存在⼀定随机性。)

1. 编写 docker-compose.yml

创建 /root/redis-sentinel/docker-compose.yml,同时 cd 到 yml 所在⽬录中。

注意 : 每个⽬录中只能存在⼀个 docker-compose.yml ⽂件

bash 复制代码
 version: '3.7'
 services:
 	sentinel1:
 		image: 'redis:5.0.9'
 		container_name: redis-sentinel-1
 		restart: always
 		command: redis-sentinel /etc/redis/sentinel.conf
 		volumes:
 			- ./sentinel1.conf:/etc/redis/sentinel.conf
 		ports:
 			- 26379:26379

 	sentinel2:
 		image: 'redis:5.0.9'
 		container_name: redis-sentinel-2
 		restart: always
 		command: redis-sentinel /etc/redis/sentinel.conf
 		volumes:
			 - ./sentinel2.conf:/etc/redis/sentinel.conf
 		ports:
 			- 26380:26379

 	sentinel3:
 		image: 'redis:5.0.9'
 		container_name: redis-sentinel-3
 		restart: always
 		command: redis-sentinel /etc/redis/sentinel.conf
 		volumes:
 			- ./sentinel3.conf:/etc/redis/sentinel.conf
 		ports:
 			- 26381:26379
	networks:
 		default:
 			external:
 				name: redis-data_default

2. 创建配置⽂件

创建 sentinel1.conf ,sentinel2.conf ,sentinel3.conf,三份⽂件的内容完全相同,都放到 /root/redis-sentinel/ ⽬录中。(redis-sentinel 在运⾏中可能会对配置进⾏ rewrite, 修改⽂件内容. 如果⽤⼀份⽂件, 就可能出现修改混乱的情况.)

bash 复制代码
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000

sentinel monitor 主节点名 主节点ip 主节点端⼝ 法定票数

  1. 主节点名:哨兵内部⾃⼰起的名字
  2. 主节点 ip:部署 redis-master 的设备 ip,此处由于是使⽤ docker,可以直接写 docker 的容器名,会被⾃动 DNS 成对应的容器 ip。
  3. 主节点端⼝:我猜大家一定都能理解端口是啥意思了
  4. 法定票数:哨兵需要判定主节点是否挂了,但是有的时候可能因为特殊情况,⽐如主节点仍然⼯作正常,但是哨兵节点⾃⼰⽹络出问题了,⽆法访问到主节点了,此时就可能会使该哨兵节点认为主节点下线,出现误判,使⽤投票的⽅式来确定主节点是否真的挂了是更稳妥的做法,需要多个哨兵都认为主节点挂了,票数 >= 法定票数 之后,才会真的认为主节点是挂了。
    sentinel down-after-milliseconds 自定义时间

主节点和哨兵之间通过⼼跳包来进⾏沟通,如果⼼跳包在指定的时间内还没回来,就视为是节点出现故障。

3. 启动所有容器

bash 复制代码
docker-compose up -d

如果启动后发现前⾯的配置有误,需要重新操作,使⽤ docker-compose down 即可停⽌并删除刚才创建好的容器。

4. 查看运行日志

bash 复制代码
docker-compose logs

上述操作必须保证⼯作⽬录在 yml 的同级⽬录中,才能⼯作。

📕4. 选举原理

假定当前环境如上⽅介绍,三个哨兵(sentenal1, sentenal2, sentenal3),⼀个主节点(redis-master),两个从节点(redis-slave1,redis-slave2)。当主节点出现故障,就会触发重新⼀系列过程。

1. 主观下线

当 redis-master 宕机,此时 redis-master 和三个哨兵之间的⼼跳包就没有了,此时,站在三个哨兵的⻆度来看,redis-master 出现严重故障,因此三个哨兵均会把 redis-master 判定为主观下线 (SDown)。

2. 客观下线

哨兵 sentenal1,sentenal2,sentenal3 均会对主节点故障这件事情进⾏投票,当故障得票数 >= 配置的法定票数之后,此时意味着 redis-master 故障这个事情被做实了,此时触发客观下线 (ODown)。

3. 选举出哨兵的 leader

选举过程涉及到 Raft 算法

假定⼀共三个哨兵节点, S1, S2, S3

  1. 每个哨兵节点都给其他所有哨兵节点,发起⼀个 "拉票请求"。 (S1 -> S2, S1 -> S3, S2 -> S1, S2 -> S3, S3 -> S1, S3 -> S2)

  2. 收到拉票请求的节点,会回复⼀个 "投票响应",响应的结果有两种可能,投 or 不投。

⽐如 S1 给 S2 发了个投票请求,S2 就会给 S1 返回投票响应。到底 S2 是否要投 S1 呢? 取决于 S2 是否给别⼈投过票了(每个哨兵只有⼀票),如果 S2 没有给别⼈投过票,换⽽⾔之,S1 是第⼀个向 S2 拉票的,那么 S2 就会投 S1,否则就不投。

  1. ⼀轮投票完成之后,发现得票超过半数的节点,⾃动成为 leader。

如果出现平票的情况 (S1 投 S2, S2 投 S3, S3 投 S1, 每⼈⼀票),就重新再投⼀次即可,这也是为啥建议哨兵节点设置成奇数个的原因,如果是偶数个,则增⼤了平票的概率,带来不必要的开销。

  1. leader 节点负责挑选⼀个 slave 成为新的 master,当其他的 sentenal 发现新的 master 出现了,就说明选举结束了。

4. leader 挑选出合适的 slave 成为新的 master

挑选规则:

  1. ⽐较优先级,优先级⾼(数值⼩的)的上位,优先级是配置⽂件中的配置项( slave-priority 或者replica-priority )。
  2. ⽐较 replication offset 谁复制的数据多,⾼的上位。
  3. ⽐较 run id,谁的 id ⼩,谁上位。

当某个 slave 节点被指定为 master 之后:

  1. leader 指定该节点执⾏ slave no one ,成为 master。
  2. leader 指定剩余的 slave 节点,都依附于这个新 master。
相关推荐
蒂法就是我3 小时前
java集合类的底层类是哪个
java·开发语言
canonical_entropy3 小时前
范式重构:可逆计算如何颠覆DDD的经典模式
后端·低代码·领域驱动设计
绝无仅有3 小时前
某大厂跳动Java面试真题之问题与解答总结(五)
后端·面试·github
我是天龙_绍3 小时前
SpringBoot如何整合Mybatis-Plus
后端
绝无仅有3 小时前
某大厂跳动Java面试真题之问题与解答总结(四)
后端·面试·github
Hoking3 小时前
LangChain4j集成SpringBoot接入百炼大模型(Qwen)
java·人工智能·spring boot·llm
玉面小白龍(peng)3 小时前
sql优化进阶
数据库
Adorable老犀牛3 小时前
Linux-db2look创建表结构详细参数
linux·数据库·db2
浪里小白龙593 小时前
零信任平台接入芋道框架
java