「一发入魂」Redis哨兵机制(redis哨兵的作用)
mhr18 2024-10-26 10:54 35 浏览 0 评论
本章内容
主要功能
Redis的主从架构中,当主服务器宕机,从服务器切换成主服务器的过程需要人工参与。 为此,Redis2.8版本后提供了哨兵工具来实现自动化的系统监控和故障恢复功能。
哨兵的主要作用是监控Redis系统的运行状况。主要功能:
- 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
- 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并将其他从节点更新为新主节点的从节点。
- 通知(Notification):哨兵通过pub/sub机制将故障转移的结果发送给客户端。
- 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
其中:
- 监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移。
- 通知和配置提供者功能,使得客户端可以及时发现Redis集群的变更。
哨兵集群监控逻辑,如图所示:
核心原理
哨兵是一个运行在特殊模式下的Redis进程,与Redis主从实例一起运行,其核心功能主要有三项:监控、选主和通知。
监控
哨兵集群组建
哨兵搭建
组建一个由三个Redis节点192.168.31.106:6379(主节点)、192.168.31.106:6380(从节点-1)、192.168.31.106:6381(从节点-2)组成的Redis主从集群。
从Redis源码目录复制三份哨兵配置文件sentinel.conf,修改内容如下:
# sentinel实例端口
port 26379
# sentinel monitor <被监控主节点名称(此处可自定义)> <被监控主节点ip> <被监控主节点port> <quorum>
# quorum:只有超过quorum数量的哨兵认为主机已死,才能推举新的主机,quorum值最好超过Sentinel数量(单数)的一半
sentinel monitor master 192.168.31.106 6379 2
分别启动三个哨兵节点,执行命令:
redis-sentinel sentinel.conf
至此,由三个哨兵节点组成的哨兵架构搭建完成。
集群组建
哨兵搭建完成后,通过Redis提供的发布/订阅(pub/sub)机制实现哨兵实例之间的相互通信。
在主从集群中,Redis主库中有一个名为__sentinel__:hello的channel(频道),哨兵之间通过该频道进行交互,实现互相通信。如图所示:
图中,哨兵-1将自身的IP(192.168.31.106)和端口(26379)发布到Redis主库的频道(__sentinel__:hello)中,由于哨兵-2和哨兵-3订阅了该频道,因此哨兵-2和哨兵-3就可以从该频道中获取哨兵-1的IP和端口,这样哨兵-2、哨兵-3就顺利与哨兵1建立了网络连接。
以同样的方式,哨兵-2和哨兵-3也可以建立网络连接,至此,哨兵集群就形成了。之后哨兵集群通过该频道实现哨兵节点之间的信息交互(如:判定主库主观下线和客观下线)。
主从集群监控
哨兵集群组建完成后,哨兵通过向主节点发送INFO命令来获取主从集群中的从节点列表,根据返回的从节点列表中的连接信息与每个从节点建立连接,并基于该连接对从节点进行持续监控。如图所示:
下线判断
Redis主节点下线判断分为主观下线和客观下线。
主观下线(SDOWN):每个Sentinel会以每秒一次的频率向整个集群中的主节点、从节点以及其他Sentinel发送PING命令;如果一个实例(Instance)距离最后一次有效回复PING命令的时间超过参数down-after-milliseconds(默认值为30000,即:30s)设定的值, 则该实例会被Sentinel标记为主观下线。
客观下线(ODOWN):如果一个主节点被标记为主观下线,则正在监视该主节点的所有Sentinel会以每秒一次的频率确认该主节点是否真的进入主观下线状态;当有足够数量的Sentinel(大于等于配置文件中参数quorum设定的值)在指定时间范围内确认该主节点进入主观下线状态, 则标记该主节点为客观下线。
Sentinel询问其他Sentinel是否同意主节点已下线命令:sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>。
发送命令:sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
ip:主观下线的服务ip
port:主观下线的服务端口
current_epoch:sentinel的纪元
runid:*表示检测服务下线状态,如果是sentinel的运行id,表示用来选举领头sentinel
其他Sentinel向源Sentinel返回一条包含三个参数的Multi Bulk信息作为sentinel is-master-down-by命令的回复:
回复内容主要包含三个参数:
down_state:1表示已下线,0表示未下线
leader_runid:领头sentinal runid
leader_epoch:领头sentinel纪元
如果源Sentinel发送的runid参数是*,则说明是确认主观下线,忽略leader_runid和leader_epoch参数;
如果源Sentinel发送的runid参数是源Sentinel的runid,则说明是Sentinel Leader选举,忽略down_state参数。
如图所示:
图中,哨兵-2判定主节点主观下线,向其他哨兵(哨兵-1、哨兵-3)发送is-master-down-by-addr命令,哨兵-1和哨兵-3根据自身与主节点的连接情况做出Y或N的响应(Y-下线,N-在线)。如果下线票数大于等于哨兵配置文件中的参数quorum设定的值(如:quorum=2),则判定主节点客观下线。
选主
选主指的是从Redis的所有从节点中选择一个从节点作为新的主节点。主要步骤包括哨兵选举、主节点选举、故障转移。
哨兵选举
判定Redis主节点客观下线后,需要从Redis集群的所有从节点中选择一个从节点作为Redis集群新的主节点。
具体由哨兵集群中的某个哨兵来完成Redis集群的主从切换,需要根据哨兵集群的选举机制产生。哨兵集群的选举机制是基于Raft算法。
选举流程:
- 1)判断客观下线的Sentinel节点分别向其他Sentinel节点发送自身的runId,请求将自己设置为Leader。
- 2)其他Sentinel节点收到请求后回复是否同意该节点成为Leader,根据先到先得原则,如果Sentinel节点已选择某个Sentinel节点(如:Sentinel-1)为Leader,则会拒绝其他Sentinel节点(即:Sentinel-2、Sentinel-3)的选举请求。
- 3)根据选举票数是否达到预定值(大于等于quorum和Sentinel节点数/2+1的最大值)来判定该节点是否成为Leader,达到预定值则选举完成,否则进入下一轮选举。
主节点选举
选举产生Sentinel Leader后,由Sentinel Leader从Redis集群的所有从节点中选举一个从节点作为新的主节点。
主节点选举流程:
- 1)筛选从节点,从所有从节点中过滤掉在线状态或网络连接状态(参数down-after-milliseconds)异常的从节点。
- 2)选择优先级slave-priority(配置项)最大的从节点作为主节点,如果slave-priority相同则继续比较从节点的复制偏移量。
- 3)选择复制偏移量最大的从节点作为主节点,如果复制偏移量相同则继续比较从节点的runId。
- 4)选择runId最小的从节点作为主节点。
故障转移
选举出Redis集群主节点后,需要根据已选举出来的主节点进行故障转移。
主要步骤:
- 1)被选举为主节点的从节点执行replicaof no one(Redis5.0以前为saveof no one) 命令脱离原主节点,使之升级为新的主节点。
- 2)其他从节点节点通过replicaof new master命令成为新主节点的从节点。
- 3)原主节点恢复后,将其设置为新主节点的从节点。
通知
哨兵节点在故障转移完成后,会将新的主节点信息发送给客户端,以便客户端及时切换主节点。
基于pub/sub机制的事件通知
哨兵是一个运行在特定模式下的Redis实例,它并不服务于请求操作,只是完成监控、选主和通知等任务。每个哨兵实例提供了pub/sub机制,客户端可以从哨兵实例中订阅消息。
哨兵提供了很多消息订阅频道(如:主库下线判断、新主库选定、从库重新配置等)。
客户端订阅频道
客户端通过读取哨兵的配置文件,获得哨兵的地址和端口与其建立网络连接,并在客户端执行订阅命令来获取不同的事件消息。如:
subscribe +switch-master
工作流程
哨兵机制的主要工作流程:
- 1)每个Sentinel以2秒/次的频率通过Master节点的频道(_sentinel_:hello)交换信息(如:组建哨兵集群、下线判断)。
- 2)每个Sentinel以10秒/次的频率向Master和Slave发送INFO命令,获取Redis集群的从节点列表并确定主从关系(监控Redis集群)。
- 3)每个Sentinel以1秒/次的频率向整个集群中的Master、Slave以及其他Sentinel发送一个PING命令(心跳检测)。
- 4)如果一个实例(Instance)距离最后一次有效回复PING命令的时间超过参数down-after-milliseconds设定的值, 则该实例会被Sentinel标记为主观下线。
- 5)当有足够数量的Sentinel(大于等于配置文件中参数quorum指定的值)确认Master进入了主观下线状态, 则Master会被标记为客观下线(注意:若没有足够数量的Sentinel确认Master客观下线, Master的客观下线状态就会被移除。若此时Master重新向Sentinel发送PING命令并得到有效回复,则Master的主观下线状态也会被移除)。
- 6)判定Master客观下线后,从Sentinel集群中选举一个Sentinel Leader节点来完成Redis集群的主从切换。
- 7)主从切换完成后,根据新选举出来的Master节点完成Redis集群故障转移。
【阅读推荐】
更多精彩内容请移步【南秋同学】个人主页查阅Redis系列合集(持续更新中)。
想了解常用数据结构与算法(如:数组、链表、栈、队列、快速排序、堆与堆排序、二分查找、动态规划、广度优先搜索算法、深度优先搜索算法等)的同学请移步->数据结构与算法系列合集(持续更新中)。
【作者简介】
一枚热爱技术和生活的老贝比,专注于Java领域,关注【南秋同学】带你一起学习成长~
相关推荐
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
-
在企业级运维、故障排查和性能调优过程中,准确了解服务器的运行环境至关重要。无论是物理机还是虚拟机,都存在各自的优势与限制。在很多场景下,尤其是当你继承一台服务器而不清楚底层硬件细节时,如何快速辨识它是...
- 第四节 Windows 系统 Docker 安装全指南
-
一、Docker在Windows上的运行原理(一)架构限制说明Docker本质上依赖Linux内核特性(如Namespaces、Cgroups等),因此在Windows系统上无法直...
- C++ std:shared_ptr自定义allocator引入内存池
-
当C++项目里做了大量的动态内存分配与释放,可能会导致内存碎片,使系统性能降低。当动态内存分配的开销变得不容忽视时,一种解决办法是一次从操作系统分配一块大的静态内存作为内存池进行手动管理,堆对象内存分...
- Activiti 8.0.0 发布,业务流程管理与工作流系统
-
Activiti8.0.0现已发布。Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎。Activiti可以...
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
-
MyBatis动态SQL在日常开发中频繁使用,但大多数开发者仅掌握基础标签。本文将介绍五种高阶技巧,助你解锁更灵活的SQL控制能力。一、智能修剪(Trim标签)应用场景:动态处理字段更新,替代<...
- Springboot数据访问(整合Mybatis Plus)
-
Springboot整合MybatisPlus1、创建数据表2、引入maven依赖mybatis-plus-boot-starter主要引入这个依赖,其他相关的依赖在这里就不写了。3、项目结构目录h...
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
-
见证了两个月前勇士与猛龙那个史诗般的系列赛后,甲骨文球馆正式成为了历史。那个大大的红色标志被一个字母一个字母地移除,在周四,一切都成为了过去式。然而这座,别名为“Roaracle”(译注:Roar怒吼...
- Mybatis入门看这一篇就够了(mybatis快速入门)
-
什么是MyBatisMyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为M...
- Springboot数据访问(整合druid数据源)
-
Springboot整合druid数据源基本概念SpringBoot默认的数据源是:2.0之前:org.apache.tomcat.jdbc.pool.DataSource2.0及之后:com.z...
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
-
什么是/etc/profile.d/目录?/etc/profile.d/目录是Linux系统不可或缺的一部分保留配置脚本。它与/etc/profile文件相关联,这是一个启动脚本,该脚...
- 企业数据库安全管理规范(企业数据库安全管理规范最新版)
-
1.目的为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。2.适用范围本规范中所定义的数据管理内容,特指存放在信息系统数据库...
- Oracle 伪列!这些隐藏用法你都知道吗?
-
在Oracle数据库中,有几位特殊的“成员”——伪列,它们虽然不是表中真实存在的物理列,但却能在数据查询、处理过程中发挥出意想不到的强大作用。今天给大家分享Oracle伪列的使用技巧,无论...
- Oracle 高效处理数据的隐藏神器:临时表妙用
-
各位数据库搬砖人,在Oracle的代码世界里闯荡,处理复杂业务时,是不是总被数据“搅得头大”?今天给大家安利一个超实用的隐藏神器——临时表!当你需要临时存储中间计算结果,又不想污染正式数据表...
- Oracle 数据库查询:多表查询(oracle多表关联查询)
-
一、多表查询基础1.JOIN操作-INNERJOIN:返回两个表中满足连接条件的匹配行,不保留未匹配数据。SELECTa.emp_id,b.dept_nameFROMempl...
- 一文掌握怎么利用Shell+Python实现多数据源的异地备份程序
-
简介:在信息化时代,数据安全和业务连续性已成为企业和个人用户关注的焦点。无论是网站数据、数据库、日志文件,还是用户上传的文档、图片等,数据一旦丢失,损失难以估量。尤其是当数据分布在多个不同的目录、服务...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
- 第四节 Windows 系统 Docker 安装全指南
- C++ std:shared_ptr自定义allocator引入内存池
- Activiti 8.0.0 发布,业务流程管理与工作流系统
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
- Springboot数据访问(整合Mybatis Plus)
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
- Mybatis入门看这一篇就够了(mybatis快速入门)
- Springboot数据访问(整合druid数据源)
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)