哨兵机制原理详解

news2024/11/18 5:32:18

文章目录

  • 初始化 Sentinel
  • 三个定时任务(重要)
    • INFO任务
    • 订阅/发布任务
    • 心跳任务
  • Redis节点下线判断
    • 主观下线判断
    • 客观下线判断
  • Sentinel Leader 选举
  • 故障转移过程
    • 整体过程
    • Master 选择算法
    • 修改从服务器的复制目标
    • 将旧的主服务器变为从服务器
  • 节点上线
    • 原Redis节点上线
    • 新Redis节点上线
    • Sentinel节点上线

初始化 Sentinel

初始化 Sentinel 的最后一步是创建连向 master 的网络连接,Sentinel将成为 master 的客户端,它可以向主服务器发送命令,并从命令回复中获取相关的信息。
对于每个被 Sentinel 监视的主服务器来说,Sentinel 会创建两个连向主服务器的异步网络连接:

  1. 命令连接:这个连接专门用于向主服务器发送命令,并接收命令回复。
  2. 订阅连接:这个连接专门用于订阅主服务器的 __sentinel__ :hello 频道。

为什么要建立两个连接:

在Redis目前的发布与订阅功能中,被发送的信息都不会保存在Redis服务器里面,如果在信息发送时,想要接收信息的客户端不在线或者断线,那么这个客户端就会丢失这条信息。因此,为了不丢失__sentinel__:hello频道的任何信息,Sentinel必须专门用一个订阅连接来接收该频道的信息。

另一方面,除了订阅频道之外,Sentinel还必须向主服务器发送命令,以此来与主服务器进行通信,所以Sentinel还必须向主服务器创建命令连接。

因为Sentinel需要与多个实例创建多个网络连接,所以Sentinel使用的是异步连接。

三个定时任务(重要)

Sentinel 维护着三个定时任务以监测 Redis 节点及其它 Sentinel 节点的状态。

INFO任务

在 Sentinel 的配置文件中有 master 的IP和端口号,所以 Sentinel 在初始时是知道 master 节点的位置,于是 Sentinel 可以向 master 建立命令连接和订阅连接。
image-20230518225031229
Sentinel默认会以每十秒一次的频率,通过命令连接向 master 发送 INFO 命令,并通过分析 master 返回的 INFO 命令回复更新主从节点的相关信息。下面是INFO命令的回复的例子:

# Server
...
run_id:7611c59dc3a29aa6fa0609f841bb6a1019008a9c
...
# Replication
role:master
...
slave0:ip=127.0.0.1,port=11111,state=online,offset=43,lag=0
slave1:ip=127.0.0.1,port=22222,state=online,offset=43,lag=0
slave2:ip=127.0.0.1,port=33333,state=online,offset=43,lag=0
...
# Other sections
...

Sentinel 可以获取以下两方面的信息:

  1. 一方面是关于 master 本身的信息,包括master的运行ID(run_id:7611c59······a9c),以及master的角色(role:master)。
  2. 另一方面是关于master属下所有slave的信息,每个slave都由一个"slave"字符串开头的行记录,每行的ip域记录了slave的IP地址,而port域则记录了slave的端口号。根据这些IP地址和端口号,Sentinel无须用户提供slave的地址信息,就可以自动发现slave。

当 Sentinel 发现slave的IP和端口号之后就可以向slave发起命令连接和订阅连接,从而获得slave更加具体的信息。Sentinel向slave发送INFO命令,会得到类似如下的回复:

# Server
...
run_id:32be0699dd27b410f7c90dada3a6fab17f97899f
...
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
slave_repl_offset:11887
slave_priority:100
# Other sections
...

根据INFO命令的回复,Sentinel会提取出以下信息:

  1. slave的运行ID(run_id)。
  2. slave的角色role。
  3. master的IP地址master_host,以及master的端口号master_port。
  4. master的连接状态master_link_status。
  5. slave的优先级slave_priority。
  6. slave的复制偏移量slave_repl_offset。

根据这些信息,Sentinel会对slave的相关信息进行更新。

总结:
Sentinel 每隔10s就会通过命令连接向所有的master和slave节点发送INFO命令,根据命令的回复,sentinel可以知道master和slave的各种详细信息,并更新相关数据。

订阅/发布任务

当Sentinel与一个master或者slave建立起订阅连接之后,Sentinel就会通过订阅连接,向服务器发送以下命令:

SUBSCRIBE __sentinel__:hello

Sentinel对 __sentinel__:hello 频道的订阅会一直持续到Sentinel与Redis节点的连接断开为止。 订阅成功后,每个 Sentinel 节点每 2 秒就会向每个 Redis 节点发布一条__sentinel__ :hello 主题的信息(通过命令连接发送publish命令),当 Redis 节点中该主题的信息发生了变化,就会立即通知到所有订阅者(Sentinel)。举个例子,假设现在有sentinel1、sentinel2、sentinel3三个Sentinel在监视同一个master,那么当sentinel1向master的 __sentinel__ :hello 频道发送一条信息时,所有订阅了 __sentinel__ :hello 频道的Sentinel(包括sentinel1自己在内)都会收到master的返回信息。

当一个Sentinel从 __sentinel__:hello 频道收到一条信息时,Sentinel会对这条信息进行分析,提取出信息中的Sentinel IP地址、Sentinel端口号、Sentinel运行ID等八个参数(通过这些信息,当前的Sentinel就可以知道其他Sentinel的IP和端口号,从而向其他Sentinel建立连接),并进行以下检查:

  • 如果本地信息中记录的Sentinel运行ID和接收信息的Sentinel的运行ID相同,那么说明这条信息是Sentinel自己发送的,Sentinel将丢弃这条信息,不做进一步处理。
  • 如果本地信息中记录的Sentinel运行ID和接收信息的Sentinel的运行ID不相同,那么说明这条信息是监视同一个Redis节点的其他Sentinel发来的,接收信息的Sentinel将根据信息中的各个参数,对相应master节点的相关信息进行更新(Sentinel节点本地存储了master节点的相关信息,对这里面的信息进行更新)。
  • 如果接收信息的Sentinel的运行ID在本地中不存在,那么说明有新建立的Sentinel节点对master节点的监控,当前Sentinel节点会在master的记录中增加一条新Sentinel节点的信息。

当Sentinel通过频道信息发现一个新的Sentinel时,它不仅会为新Sentinel创建相关记录信息,还会创建一个连向新Sentinel的命令连接,而新Sentinel也同样会创建连向这个Sentinel的命令连接,最终监视同一master的多个Sentinel将形成相互连接的网络。

Sentinel之间不会创建订阅连接
Sentinel在连接master或者slave时,会同时创建命令连接和订阅连接,但是在连接其他Sentinel时,却只会创建命令连接,而不创建订阅连接。这是因为Sentinel需要通过接收master或者slave发来的频道信息来发现未知的新Sentinel,所以才需要建立订阅连接,而相互已知的Sentinel只要使用命令连接来进行通信就足够了。

总结:

每个 Sentinel 节点每 2 秒就会向每个 Redis 节点发布一条消息。因为一个Sentinel可以通过分析接收到的频道信息来获知其他Sentinel的存在,并通过发送频道信息来让其他Sentinel知道自己的存在,所以用户在使用Sentinel的时候并不需要提供各个Sentinel的地址信息,监视同一个master的多个Sentinel可以自动发现对方。

心跳任务

在默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的节点(包括master、slave、其他Sentinel在内)发送PING命令,并通过节点返回的PING命令回复来判断节点是否在线。

节点对PING命令的回复可以分为以下两种情况:

  1. 有效回复:实例返回+PONG、-LOADING、-MASTERDOWN三种回复的其中一种。
  2. 无效回复:实例返回除+PONG、-LOADING、-MASTERDOWN三种回复之外的其他回复,或者在指定时限内没有返回任何回复。

Redis节点下线判断

主观下线判断

Sentinel配置文件中的down-after-milliseconds选项指定了Sentinel判断Redis节点进入主观下线所需的时间长度:如果一个节点在down-after-milliseconds毫秒内,连续向Sentinel返回无效回复,那么Sentinel会修改这个节点的相关消息,把该节点的flags属性增加SRI_S_DOWN标识,以此来表示这个实例已经进入主观下线状态。

用户设置的down-after-milliseconds选项的值,不仅会被Sentinel用来判断master的主观下线状态,还会被用于判断master属下的所有slave,以及所有同样监视这个master的其他Sentinel的主观下线状态。举个例子,如果用户向Sentinel设置了以下配置:

sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 30000

那么30000毫秒会成为Sentinel判断master、master属下所有slave、监视该master的其他Sentinel进入主观下线的标准。

注意:在Redis的分布式集群中,多个Sentinel设置的主观下线时长可能不同。这样可能会造成Sentinel1认为master主观下线,而Sentinel2并不认为master主观下线的情况。

客观下线判断

当Sentinel将一个master判断为主观下线之后,为了确认这个master是否真的下线了,它会向同样监视这一master的其他Sentinel进行询问,看它们是否也认为master已经进入了下线状态(可以是主观下线或者客观下线)。当Sentinel从其他Sentinel那里接收到足够数量(数量大于等于 quorum )的已下线判断之后,Sentinel会将master的flags属性增加SRI_O_DOWN标识,表示master已经进入客观下线状态,并对master执行故障转移操作。

Sentinel Leader 选举

当 Sentinel 节点对 master 做出客观下线判断后会由 Sentinel Leader 来完成后续的故障转移,即 Sentinel 集群中的节点也并非是对等节点,是存在 Leader 与 Follower 的。

Sentinel 集群的 Leader 选举是通过 Raft 算法实现的。Raft 算法比较复杂,详见:Raft算法详解 - 知乎 。这里仅简单介绍一下大致思路。

每个选举参与者都具有当选 Leader 的资格,当其完成了“客观下线”判断后,就会立即“毛遂自荐”推选自己做 Leader,然后将自己的提案发送给所有参与者。其它参与者在收到提案后,只要自己手中的选票没有投出去,其就会立即通过该提案并将同意结果反馈给提案者,后续再过来的提案会由于该参与者没有了选票而被拒绝。当提案者收到了同意反馈数量大于等于 max(quorum,sentinelNum/2+1)时,该提案者当选 Leader。

说明:

  • 在网络没有问题的前提下,基本就是谁先做出了“客观下线”判断,谁就会首先发起Sentinel Leader 的选举,谁就会得到大多数参与者的支持,谁就会当选 Leader。

  • Sentinel Leader 选举会在次故障转移发生之前进行。

  • 故障转移结束后 Sentinel 不再维护这种 Leader-Follower 关系,即 Leader 不再存在。

故障转移过程

整体过程

在选举产生出Sentinel Leader之后,Sentinel Leader 将对已下线的master执行故障转移操作,该操作包含以下三个步骤:

  1. 在已下线master属下的所有slave里面,挑选出一个slave,并将其角色转换为master。
  2. 让已下线master属下的所有slave改为复制新的master。
  3. 将已下线的master设置为新master的slave,当这个旧的master重新上线(重启)时,它就会成为新master节点的slave。

故障转移操作第一步要做的就是在已下线的master属下的所有slave中,挑选出一个状态良好、数据完整的slave,然后向这个slave发送SLAVEOF no one命令,将这个slave转换为master。

Master 选择算法

在进行故障转移时,Sentinel Leader 需要从所有 Redis 的 Slave 节点中选择出新的 Master。其选择算法为:

  1. 删除列表中所有处于下线或者断线状态的从服务器,这可以保证列表中剩余的从服务器都是正常在线的。
  2. 删除列表中所有最近五秒内没有回复过Sentinel Leader的INFO命令的从服务器,这可以保证列表中剩余的从服务器都是最近成功进行过通信的。
  3. 删除所有与已下线master连接断开超过down-after-milliseconds*10毫秒的slave:down-after-milliseconds选项指定了判断主服务器下线所需的时间,而删除断开时长超过down-after-milliseconds*10 毫秒的从服务器,则可以保证列表中剩余的从服务器都没有过早地与主服务器断开连接,换句话说,列表中剩余的从服务器保存的数据都是比较新的。
  4. 删除replica-priority(优先级)值为 0 的 Redis节点。
  5. 在剩余 Redis 节点中选择出 replica-priority 最小的的节点列表。如果只有一个节点,则直接返回,否则,继续。
  6. 从优先级相同的节点列表中选择复制偏移量最大的节点(和已宕机的master节点的相似度最高)。如果只有一个节点,则直接返回,否则,继续。
  7. 从复制偏移值量相同的节点列表中选择动态 ID 最小的节点返回。

对最后选择的slave发送SLAVEOF no one命令之后,Sentinel Leader会以每秒一次的频率(平时是每十秒一次),向被升级的从服务器发送INFO命令,并观察命令回复中的角色(role)信息,当被升级服务器的role从原来的slave变为master时,Sentinel Leader就知道被选中的从服务器已经顺利升级为master了。

修改从服务器的复制目标

当新的主服务器出现之后,Sentinel Leader下一步要做的就是,让已下线master属下的所有slave去复制新的master,这一动作可以通过向slave发送SLAVEOF命令来实现。

将旧的主服务器变为从服务器

故障转移操作最后要做的是,将已下线的master设置为新的master的slave。因为旧的master已经下线,所以这种设置是保存在旧master的记录信息中,当旧master重新上线时,Sentinel (不是Sentinel Leader)就会向它发送SLAVEOF命令,让它成为新master的slave。

节点上线

原Redis节点上线

无论是原下线的 master 节点还是原下线的 slave 节点,只要是原 Redis 集群中的节点上线,只需启动 Redis 即可。因为每个 Sentinel 中都保存有原来其监控的所有 Redis 节点列表,Sentinel 会定时查看这些 Redis 节点是否恢复。如果查看到其已经恢复,则会命其从当前master 进行数据同步。不过,如果是原 master 上线,在新 master 晋升后 Sentinel Leader 会立即先将原 master 节点更新为 slave,并同步新master节点的数据。

新Redis节点上线

如果需要在 Redis 集群中添加一个新的节点,其未曾出现在 Redis 集群中,则上线操作只能手工完成。即添加者在添加之前必须知道当前 master 是谁,然后在新节点启动后运行slaveof 命令加入集群。

Sentinel节点上线

如果要添加的是 Sentinel 节点,无论其是否曾经出现在 Sentinel 集群中,都需要手工完成。即添加者在添加之前必须知道当前 master 是谁,然后在配置文件中修改 sentinel monitor属性,指定要监控的 master。然后启动 Sentinel 即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/548324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用Nginx实现对国家/城市以及指定IP的访问限制?

1.前言 在【如何用Nginx代理MySQL连接,并限制可访问IP】一文中,我们实现了通过Nginx代理MySQL连接,并限制了指定IP才能通过Nginx进行连接,以提高数据安全性。 该场景适用于根据具体的IP地址来进行访问限制,假如我们要…

synchronized优化原理

文章目录 一、Monitor1.1 Monitor结构 二、轻量级锁三、锁膨胀四、自旋优化五、偏向锁 一、Monitor Monitor的工作原理也是synchronized底层原理 每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁之后,该对象头的MarkWord中就被设…

怎样从“点点点”进阶到自动化测试?

为什么要学习自动化测试 在讨论这个问题之前,先来聊一下测试人员的职业发展路线,无非就是两条,技术路线和管理路线,技术路线一般就是功能测试(60%)-->自动化测试(25%)-->测试…

fio引发的一些问题

fio引发的一些问题 奇怪的255扇区在nvme驱动中插入打印语句直接编译模块加载源码编译内核 查找内核源码 奇怪的255扇区 由于块设备驱动项目需要测试读写速度,故使用fio工具,没想着深入了解,简单测个速就可以 使用tldr命令得到测试磁盘读写的…

linux内核篇-文件系统(硬盘、虚拟文件系统、文件缓存)

文件系统的意义 之前说的都是在进程在物理内存保存的数据,内存就像一个纸箱子,仅仅是一个暂存数据的地方,而且空间有限。如果我们想要进程结束之后,数据依然能够保存下来,就不能只保存在内存里,而是应该保存…

Nacos-04-@RefreshScope自动刷新原理

Nacos动态刷新原理 Nacos做配置中心的时候,配置数据的交互模式是有服务端push推送的,还是客户端pull拉取的? 短轮询 不管服务端的配置是否发生变化,不停发起请求去获取配置,比如支付订单场景中前端JS不断轮询订单支…

hadoop启动,缺少RM的进程:Error starting ResourceManager【已解决】

Error starting ResourceManager【已解决】 现象解决思路报错内容解决总结 现象 Hadoop启动后 执行jps 查看进程,缺少了 ResourceManager 解决思路 start-all.sh分别会有五个日志产生 缺少哪个进程,就去看谁的日志 报错内容 resourcemanager的log文…

基于 Linux 下的生产者消费者模型

目录 传统艺能😎概念😘特点😍优点😁基于阻塞队列的生产者消费者模型🤣模拟实现😂基于计算任务的生产者消费者模型👌 传统艺能😎 小编是双非本科大二菜鸟不赘述,欢迎米娜…

chatgpt赋能Python-python3_date

Python 3 Date介绍 Python 3是一种非常流行的编程语言,其中涉及到日期处理的功能非常强大。Python 3支持处理日期、时间和时间刻度,因此可以在各种情况下使用它来管理日期。 日期格式 Python 3支持多种日期格式,如下所示: “Y…

不怕得罪人地推荐这9本黑客书籍

[利益声明] 1、这9本都和我有些关系或缘分,也是我至少过了一遍的,虽然并没都仔细推敲,但是这些书,我还是不得不点个赞。 2、其中一本是我和 xisigr 写的:-)我并不觉得在这不能推荐,因为这本书毕竟卖得很好。 然后&am…

torch.nn.functional.normalize参数说明

torch.nn.functional.normalize参数说明 函数定义参数及功能官方说明三维数据实例解释参数dim0参数dim1参数dim2参数dim-1 参考博文及感谢 函数定义 torch.nn.functional.normalize(input, p2.0, dim1, eps1e-12, outNone) # type: (Tensor, float, int, float, Optional[Tens…

chatgpt赋能Python-python3_9怎么安装jieba库

Python3.9怎么安装jieba库 随着大数据时代的到来,中文分词是一个愈发重要的问题。而jieba是一个基于Python的中文分词工具包,具有高速、易用、解耦的特点,广受开发者的青睐。本文将介绍如何在Python3.9环境下安装jieba库。 什么是jieba库 …

微服务: Seata AT 分布式事务以及配置方式(上篇)

目录 前言简介: 1. 安装seata-at -> 1.1 先看版本, 全局搜一下 -> 1.2 版本说明 alibaba/spring-cloud-alibaba Wiki -> 1.3 选择seata-at版本 -> 1.4 下载后按照下图进行创建文件 ---> 1.4.0 先在nacos创建命名空间seata ---> 1.4.1 registry.conf…

Chrome 的骑士盾,谷歌 Security Princess 访谈

童话故事里的公主都有一种需要被保护的感觉,就像马里奥大叔在这么多年来都要在库巴手上拯救出碧姬公主一样。不过在谷歌的这位 Security Princess 却手执盾牌,守护着大家的 Chrome 浏览器免受恶意程序攻击。小编这次就乘着世界网络安全日的机会&#xff…

微信小程序-生命周期

为什么今天突然总结一下微信小程序的生命周期呢?因为突然发现这个知识点忘得有点干净。所以今天就看一下微信小程序的生命周期是怎么个事吧! 目录 生命周期 生命周期的分类 生命周期函数的作用 生命周期函数的分类 生命周期是指一个对象从创建->…

Docker -- m1芯片 macOS 安装 nginx - 03

m1芯片 macOS 安装 nginx 一、安装docker提前准备二、下载nginx相关镜像三、运行相关容器四、运行并验证 一、安装docker提前准备 查看 d o c k e r \color{#FF7D00}{docker} docker版本:在 c o m m e n t \color{#FF7D00}{comment} comment 中输入 docker -version…

小红薯笔记/帖子采集工具

小红书【笔记/帖子】采集工具 链接: http://106.53.68.168:9920/xhs-keyword-spider 规则及操作 (1)规则: 按照关键词抓取规则:标题中或者正文内容中包含该关键词都能被抓取下来。多种搜索模式可选,分别…

字节跳动10年经验,10W字228道软件测试经典面试题总结(附答案)

前言 最近有很多粉丝问我,有什么方法能够快速提升自己,通过阿里、腾讯、字节跳动、京东等互联网大厂的面试,我觉得短时间提升自己最快的手段就是背面试题,最近总结了软件测试常用的面试题,分享给大家,希望…

【mpvue】小程序开发入门

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍mpvue的使用。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习知识,共同进步。 🥞喜欢的朋友可以关注一下,下次更…

Atlassian攻略:如何将Jira和Confluence的数据平稳迁移上云

迁移到云端相当于一次专业的冒险旅⾏。过程中肯定会经历一些颠簸,但只要有正确的心态和充分的准备,您就能完美应对。最终的目的地一定会让你感觉值得。当Atlassian调查了最近迁移的客户时,有89%的客户表示在他们不到6个月的时间内就意识到了迁…