当前位置:网站首页>Redis:哨兵
Redis:哨兵
2022-08-03 18:08:00 【jchen104】
参考资料:
《渐进式解析 Redis 源码 - 哨兵 sentinel》
《深入剖析Redis系列- Redis哨兵模式与高可用集群》
前文:
写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。
目录
Redis 的主从复制模式下,一旦主节点由于故障不能提供服务,需要手动将从节点晋升为 主节点,同时还要通知客户端更新主节点地址,这种故障处理方式从一定程度上是无法接受的。Redis 2.8 以后提供了 Redis Sentinel 哨兵机制 来解决这个问题。
一、哨兵简介
1、哨兵的组成
Redis 哨兵(Sentinel)是由一个或多个 Sentinel 实例组成的 Sentinel 系统,可以监视任意多个主服务器,以及这些主服务器的所有从服务器。
Sentinel 本质上是一个运行在特殊状模式下的 Redis 服务器。Sentinel 模式下 Redis 服务器只支持 PING、SENTINEL、INFO、SUBSCRIBE、UNSUBSCRIBE、PSUBSCRIBE、PUNSUBSCRIBE 七个命令。
2、哨兵的作用
Redis官方文档的描述如下:
- 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
- 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
- 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
- 通知(Notification):哨兵可以将故障转移的结果发送给客户端。
其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现。
二、哨兵的运行机制
1、哨兵启动
当一个 Sentinel 启动时,会创建连向被监视的主服务器的网络连接。它可以向主服务器发送命令,并从命令回复中获取相关的信息。对于每个被 Sentinel 监视的主服务器,Sentinel 会创建两个连向主服务器的异步网络:
命令连接:用于向主服务器发送命令(包括ping、info),并接受命令回复,用来获取从节点的信息与Sentinel 、Redis节点的状态信息。
订阅连接:用于订阅主服务器的 __sentinel__:hello 频道,用来和其他Sentinel 实例建立连接。
2、订阅频道
Sentinel实例会向与其连接的节点(包括主从节点)的 __sentinel__:hello 频道发送消息, 并订阅该频道(SUBSCRIBE __sentinel__:hello)。这样一来,当后续的Sentinel实例与主库建立连接,发送消息时,之前订阅该频道的消息就能够收到新实例加入的消息,然后就可以从这个频道直接获取新实例的信息并建立网络连接。
以下图为例,哨兵 1 把自己的 IP(172.16.19.3)和端口(26579)发布到__sentinel__:hello频道上,哨兵 2 和 3 订阅了该频道。那么此时,哨兵 2 和 3 就可以从这个频道直接获取哨兵 1 的 IP 地址和端口号。然后,哨兵 2、3 可以和哨兵 1 建立网络连接。
Sentinel 对 __sentinel__:hello 频道的订阅会一直持续到 Sentinel 与服务器断开连接为止。在在此之前Sentinel 会以每两秒一次的频率,通过命令向所有被监视的主服务器和从服务器发送自己的信息及主节点相关的配置。
3、获取服务器信息
Sentinel 向主服务器发送 INFO 命令,获取主服务器及它的从服务器信息。
(1)获取主服务器信息
Sentinel 默认会以每十秒一次的频率,通过命令连接向被监视的主服务器发送 INFO 命令,并通过分析 INFO 命令的回复来获取主服务器的当前信息。
- 主服务自身信息:包括 run_id 域记录的服务器运行 ID,以及 role 域记录的服务器角色
- 主服务的从服务器信息:包括 IP 地址和端口号
(2)获取从服务器信息
当 Sentinel 发现主服务器有新的从服务器出现时,Sentinel 除了会为这个新的从服务器创建相应的实例结构之外,Sentinel 还会创建连接到从服务器的命令连接和订阅连接。
4、检测服务器状态
Sentinel 向 Redis 服务器发送 PING 命令,检查其状态。
每个 Sentinel 节点会以 每秒一次 的频率对 Redis 节点和 其它 的 Sentinel 节点发送 PING 命令,并通过节点的 回复 来判断节点是否在线。哨兵正是通过这个机制得以判断主节点是否下线,这将涉及到2个新的改变,主观下线与客观下线。
注意:一个有效的 PING 回复可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果 服务器 返回除以上三种回复之外的其他回复,又或者在 指定时间 内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复 无效(non-valid)。
三、故障处理
在上文中,我们留了2个概念(主观下线与客观下线)没有解释,这一节我们结合哨兵对故障的处理进行讲解。
1、主库下线判定
(1)主观下线
主观下线适用于所有 主节点 和 从节点。如果在 down-after-milliseconds 毫秒内,Sentinel 没有收到 目标节点 的有效回复,则会判定 该节点 为 主观下线。
(2)客观下线
客观下线只适用于主节点。当 Sentinel 将一个主服务器判断为主管下线后,为了确认这个主服务器是否真的下线,会向同样监视这一主服务器的其他 Sentinel 询问( 通过sentinel is-master-down-by-addr指令判断),看它们是否也认为主服务器已经下线。
其他哨兵会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票。如果赞成票数(这里是2)是大于等于哨兵配置文件中的 quorum 配置项(比如quorum=2), 则可以判定主库客观下线了。当足够数量的 Sentinel 认为主服务器已下线,就判定其为客观下线,并对其执行故障转移操作。
2、哨兵集群的选举
当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个 Sentinel 会进行选举,选举出一个领头的 Sentinel,并由领头 Sentinel 对下线主服务器执行故障转移操作。
哨兵的选举机制使用Raft(Raft算法详解)选举算法: 选举的票数大于等于num(sentinels)/2+1时,将成为领导者,如果没有超过,则继续选举。任何一个想成为 Leader 的哨兵,要满足两个条件:
- 拿到半数以上的赞成票;
- 拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。
当有3 个哨兵时,quorum 设置为 2,那么,任何一个想成为 Leader 的哨兵只要拿到 2 张赞成票,就可以了。
3、新主库的选出
主库被判定为客观下线后,就需要从剩余的从库中选择一个新的主库。
- 过滤列表中所有处于下线或断线状态的从服务器。
- 过滤列表中所有最近五秒没有回复过 Sentinel Leader 的 INFO 命令的从服务器。
- 过滤所有与已下线主服务器连接断开超过 down-after-milliseconds * 10 毫秒的从服务器(down-after-milliseconds 指定了判断主服务器下线所需的时间)。
然后, Sentinel Leader 先选出优先级最高的从服务器;如果优先级一样高,再选择复制偏移量最大的从服务器;如果结果还不唯一,则选出运行 ID 最小的从服务器。
4、故障的转移
在上文中,Sentinel Leader 已经挑选出了新的主节点,接下来就要进行故障转移了。
首先向这个从节点发送 SLAVEOF no one 命令,将其转换为主节点(5.0 中应该是replicaof no one)。然后Sentinel Leader 会向所有从节点发送 SLAVEOF 命令,让所有从节点指向新的主节点并复制新的主节点上的数据,然后通知客户端主节点已更换,最后将旧的主服务器标记为从服务器。当旧的主服务器重新上线,Sentinel Leader 会向它发送 SLAVEOF 命令,让其成为从服务器。
最后,需要注意的是,主从切换并不一定就能完成,下面举个例子,Redis 1主4从,5个哨兵,哨兵配置quorum为2,如果3个哨兵故障,此时主节点宕机。
由于quorum=2,所以当一个哨兵判断主库“主观下线”后,询问另外一个哨兵后也会得到同样的结果,2个哨兵都判定“主观下线”,达到了quorum的值,因此,哨兵集群可以判定主库为“客观下线”。
但哨兵不能完成主从切换。哨兵标记主库“客观下线后”,在选举“哨兵领导者”时,一个哨兵必须拿到超过多数的选票(5/2+1=3票)。但目前只有2个哨兵活着,无论怎么投票,一个哨兵最多只能拿到2票,永远无法达到N/2+1选票的结果。
边栏推荐
猜你喜欢
走进通信:为什么4G信号满格,却上不了网呢
云渲染的优势与劣势
JS string to GBK encoding ultra-reduced implementation
这是Facebook母公司 关于元宇宙的80万亿美元豪赌
Web3 security risks daunting?How should we respond?
荧光标记多肽FITC/AMC/FAM/Rhodamine/TAMRA/Cy3/Cy5/Cy7-Peptide
WPF implements column chart
rhel8.3 系统下修改有线网卡配置信息实现联网
全尺度表示的上下文非局部对齐,南科大&优图提出NAFS解决基于文本的Re ID
“vite”和“vite预览”有什么区别?
随机推荐
USD 能统一元宇宙吗?
想要防止数据泄漏,如何选择国产浏览器?
【JS】利用JS给删除按钮添加提示框
Postgresql 备份大小情况!
多商户商城系统功能拆解21讲-平台端分销订单
分享 14 个你必须知道的 JS 函数
How to install and start VNC remote desktop service on cloud GPU?
MySQL database account management and optimization
【汇编语言03】第2章 寄存器——实验1:查看CPU和内存,用机器指令和汇编指令编程
使用range-based for循环的注意事项
高等数学---第十章无穷级数---常数项级数
Oracle备份的几种方式
rhel8.3 系统下修改有线网卡配置信息实现联网
NLP的Taskflow API
LyScript 内存交换与差异对比
新“妖股”13个交易日暴涨320倍,市值3100亿美元超阿里
三丁基-巯基膦烷「tBuBrettPhos Pd(allyl)」OTf),1798782-17-8
mysql之数据库账户管理与优化
Crack:WebKitX ActiveX and WebKitX VHX
Flask框架——项目可安装化