从入门到精通【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。
相关推荐
oMcLin7 分钟前
如何在 Debian 10 上配置并优化 Redis 集群,确保低延迟高并发的实时数据缓存与查询
redis·缓存·debian
TDengine (老段)8 分钟前
TDengine Python 连接器进阶指南
大数据·数据库·python·物联网·时序数据库·tdengine·涛思数据
你怎么知道我是队长13 分钟前
C语言---文件读写
java·c语言·开发语言
赵渝强老师16 分钟前
【赵渝强老师】OceanBase的配置文件与配置项
数据库·oceanbase
咕白m62521 分钟前
通过 C# 快速生成二维码 (QR code)
后端·.net
踏浪无痕27 分钟前
架构师如何学习 AI:三个月掌握核心能力的务实路径
人工智能·后端·程序员
小毅&Nora1 小时前
【后端】【SpringBoot】① 源码解析:从启动到优雅关闭
spring boot·后端·优雅关闭
嘻哈baby1 小时前
从TIME_WAIT爆炸到端口耗尽:Linux短连接服务排查与优化
后端
玖日大大1 小时前
OceanBase SeekDB:AI 原生数据库的技术革命与实践指南
数据库·人工智能·oceanbase
wszy18091 小时前
外部链接跳转:从 App 打开浏览器的正确姿势
java·javascript·react native·react.js·harmonyos