当前位置: 首页 > news >正文

Redis原理之哨兵机制(Sentinel)

上篇文章:

Redis原理之主从复制https://blog.csdn.net/sniper_fandc/article/details/149141103?fromshare=blogdetail&sharetype=blogdetail&sharerId=149141103&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

目录

1 哨兵机制恢复主节点故障流程

1.1 整体流程

1.2 sentinel节点作用

2 搭建主从结构+哨兵

2.1 docker拉取redis镜像

2.2 编排redis数据节点

2.3 编排redis的哨兵节点(sentinel)

2.4 演示故障转移


        注意:从节点如何变为主节点?从节点主动执行slaveof no one命令,此时从节点变为主节点。但是如果是主节点挂了,从节点是不会自动变为主节点的。此时只有人工干预来选择哪个从节点变为主节点,需要改变主从模式的拓扑结构,比较麻烦。而哨兵机制正式解决该问题的手段。

        哨兵机制:Redis提供的高可用性的实现方案,它是独立的redis-sentinel进程,不属于redis提供的redis-server进程。

1 哨兵机制恢复主节点故障流程

1.1 整体流程

        哨兵节点会和数据节点建立TCP长连接,并采用心跳包机制,定期向数据节点发送ping,数据节点需要回复pong。如果哨兵节点没有收到pong响应,就会认为该节点不可达(发生故障)。如果是slave节点故障,对读写没有太大影响;如果是master节点故障,则哨兵节点开始工作:

        1.master节点故障,主从复制终止。

        2.sentinel节点发现master故障(主观下线),与其他sentinel进行“协商”,需要大多数sentinel都认为master故障客观下线),此时才会确认真正发生master故障(只有一个sentinel认为master故障不一定正确,因为可能是因为该sentinel节点发生网络抖动,从而导致没有收到pong,而实际可能master正常工作)。

        3.sentinel节点之间通过Raft算法选举一位作为领导(leader),leader负责故障转移过程。

        注意:Raft算法要求每个哨兵节点只有一票,率先发现故障的先发起自身成为leader的投票,其他哨兵节点先收到谁的投票就先投给谁,达到法定投票的节点成为leader。按照Raft算法规则,谁先发现故障,谁就更可能成为leader。因为偶数节点数有较大可能出现平票,因此最好选择奇数节点个数的哨兵

        4.故障转移:leader远程控制某个slave执行slaveof no one命令,则该slave晋升为master节点,然后再控制其他slave进行slaveof到新的master节点,维护主从拓扑关系。当故障转移后,leader会将新的master(ip和端口号)和拓扑关系通知其他客户端。

        注意:leader选择slave的三个指标。先看优先级(配置文件的slave-priority或replica-priority),数值越小越优先;优先级一样再看offset偏移量,数值越大越优先(说明数据量越接近原来的master);前两个指标都一样最后看run id,值越小越优先(由于run id是节点运行时redis自动随机生成,因此这个指标实际上也是随机选slave)。

1.2 sentinel节点作用

        1.监控:监控所有的数据节点和其他哨兵节点。

        2.故障转移:master发生故障后负责从slave选择新的master节点并维护主从拓扑结构。

        3.通知:将故障转移后的新master节点和拓扑关系通知给客户端。

        注意:sentinel节点数量通常设为奇数比较好,一般是3个。

2 搭建主从结构+哨兵

        由于搭建真实的多物理机的redis节点成本较高,因此这里使用容器化技术来进行搭建。需要提前安装docker和docker-compose,docker简单来讲是一个类似虚拟机的容器,它小巧轻量,提供了容器来统一配置环境信息,尤其是在多服务的环境中,配置很容易出现冲突,使用docker创建容器就可以实现多个服务的环境配置的冲突隔离。

        docker-compose是容器编排工具,在docker中如果容器较多就容易出现多个容器之间的依赖关系(比如先后启动顺序),使用docker-compose就可以帮助我们进行管理。

2.1 docker拉取redis镜像

        使用命令来拉取redis的镜像(拉取之间需要停掉所有的redis服务):

        docker pull redis:5.0.9

2.2 编排redis数据节点

        编排就是用yml文件来配置多个容器的信息,包括但不限于创建什么容器、容器参数信息(名称、端口号等等),通过一个命令就能批量启动这些容器。

        这里搭建一主两从的主从结构,需要定义docker-compose.yml文件(文件名不能变)。

version: '3.7'services:master:image: 'redis:5.0.9'container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: 'redis:5.0.9'container_name: redis-slave1restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6380:6379slave2:image: 'redis:5.0.9'container_name: redis-slave2restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6381:6379

        其中,services下的master、slave1和slave2是服务的名字(自己起),image则是容器基于的镜像,container_name是容器名称,restart是如果节点挂了是否重启,command则是启动节点的方式,ports是端口映射(把物理机的端口映射到容器的端口,容器端口和物理机端口独立,容器端口和容器端口独立,映射了后就可以让物理机访问容器)。

        使用命令docker-compose up -d(-d表示后台方式启动)即可启动这三个容器:

        这里可以使用redis-cli -p 6379来连接启动的节点:

        注意:为什么不把3个数据节点和3个哨兵节点放到一个yml文件?因为如果是哨兵节点先启动,就会认为master节点故障,从而故障转移,但是此时数据节点还未启动,因此这样操作无效。虽然不会对全局容器产生影响,但是对于执行日志的观察不利。

2.3 编排redis的哨兵节点(sentinel)

        这里操作和上述一样:

version: '3.7'services:sentinel1:image: 'redis:5.0.9'container_name: redis-sentinel-1restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel1.conf:/etc/redis/sentinel.confports:- 26379:26379sentinel2:image: 'redis:5.0.9'container_name: redis-sentinel-2restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel2.conf:/etc/redis/sentinel.confports:- 26380:26379sentinel3:image: 'redis:5.0.9'container_name: redis-sentinel-3restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel3.conf:/etc/redis/sentinel.confports:- 26381:26379networks:default:external: truename: redis-data_default

        由于sentinel启动依赖配置文件sentinel.conf,而在运行过程中sentinel会对配置文件进行修改来适应具体节点的情况(配置重写rewrite),因此不能使用同一个配置文件。volumes参数则描述了配置文件分别映射为三个文件,初始状态一样,但是一旦启动文件内容就会发生变化。这三个配置文件(sentinel1.conf、sentinel2.conf和sentinel3.conf)内容如下:

bind 0.0.0.0port 26379sentinel monitor redis-master redis-master 6379 2sentinel down-after-milliseconds redis-master 1000

        bing描述哨兵可被所有ip访问,port描述哨兵的端口号,

        sentinel monitor依次描述监控哪个主节点、主节点ip(这里使用主节点名称类似域名,docker可自动解析为ip)、主节点端口号、法定选票(少数服从多数,达到选票数量才会一致认为master出现故障)。

        sentinel down-after-milliseconds描述了心跳包超时时间,超过这个时间没有接收到pong就认为master出现故障。

        同时,由于使用docker-compose启动一组容器,这相当于创建一个局域网(网络名是docker-compose.yml所在的目录+_default)。如果没有networks字段的配置,这组sentinel节点就又创建了一个局域网,两个局域网无法直接互相访问。因此需要把这组节点加入到数据节点所在的局域网中,配置networks字段的原因正是上述阐述。

        使用命令:docker network ls可以查看创建的局域网:

        具体操作结果如下:

        注意:上述操作中如果启动容器失败,就需要检查配置文件,然后使用命令docker-compose down来关闭容器,再重新启动。使用命令docker-compose logs可以查看docker容器的日志上述和docker容器相关的命令必须在yml文件同级的目录下进行。

        使用命令docker ps -a查看目前启动的容器:

2.4 演示故障转移

        使用docker stop redis-master命令关闭master节点:

        观察日志发现,sdown表示主观下线,即sentinel-3哨兵节点首先发现master故障。odown表示客观下线,sentinel-3获得的票数达到法定票数(2票):

        下图表示投票记录,其他两个哨兵节点均给sentinel-3进行投票,因此sentinel-3成为leader:

        sentinel-3作为leader选择ip为172.18.0.4的slave节点(端口号为6380)为新的master,而172.18.0.2的节点是故障的master节点:

        观察6380的节点,role已经变成master,同时只有一个从节点连接,从节点的ip是182.18.0.3(端口号为6381):

        如果使用docker start redis-master命令让原来的master恢复,则它不会变为master,而是成为从节点:

        由此可见,哨兵节点自动的完成了从监控=>发现故障=>选举leader=>leader故障转移=>转移完成通知的过程,极大的保证了主从复制的高可用性。

下篇文章:

http://www.lryc.cn/news/592566.html

相关文章:

  • Android性能优化之网络优化
  • 【锂电池剩余寿命预测】TCN时间卷积神经网络锂电池剩余寿命预测(Pytorch完整源码和数据)
  • 如何用Python并发下载?深入解析concurrent.futures 与期物机制
  • 安卓Android项目 报错:系统找不到指定文件
  • python学智能算法(二十四)|SVM-最优化几何距离的理解
  • 【52】MFC入门到精通——MFC串口助手(二)---通信版(发送数据 、发送文件、数据转换、清空发送区、打开/关闭文件),附源码
  • 『 C++ 入门到放弃 』- set 和 map 容器
  • Java Web项目Dump文件分析指南
  • 开源Docmost知识库管理工具
  • spring-cloud微服务部署转单体部署-feign直连调用
  • Windows Server 版本之间有什么区别?
  • 在断网情况下,网线直接连接 Windows 笔记本和 Ubuntu 服务器进行数据传输
  • 华为业务变革项目IPD基本知识
  • 【HCI log】Google Pixel 手机抓取hci log
  • 京东店铺入鼎的全面分析与自研难度评估
  • 70 gdb attach $pid, process 2021 is already traced by process 2019
  • CCF编程能力等级认证GESP—C++4级—20250628
  • 协作机器人操作与编程-PE系统示教编程和脚本讲解(直播回放)
  • 自动化面试题
  • 搜广推校招面经九十五
  • 基于 WinForm 与虹软实现人脸识别功能:从理论到实践
  • 关于我用AI编写了一个聊天机器人……(11)
  • 《每日AI-人工智能-编程日报》--2025年7月18日
  • [JS逆向] 微信小程序逆向工程实战
  • 加速度计和气压计、激光互补滤波融合算法
  • 6月零售数据超预期引发市场波动:基于AI多因子模型的黄金价格解析
  • # Redis-stable 如何在Linux系统上安装和配置
  • 编译器没找到 esp_http_client.h,
  • 算法竞赛备赛——【图论】求最短路径——小结
  • 【CF】⭐Day104——Codeforces Round 840 (Div. 2) CE (思维 + 分类讨论 | 思维 + 图论 + DP)