redis------第七天学习笔记(哨兵机制:主库挂了,如何不间断服务?)

redis------学习笔记(哨兵机制:主库挂了,如何不间断服务?)

上次学习了主从库集群模式。在这个模式下,如果从库发生了故障,在这个模式下,如果从库也发生故障了,客户端可以继续向主库或者其他从库发送请求,进行相关的操作,但是如果主库发生故障,那就直接影响到从库的同步,因为从库没有相应的主库可以进行数据复制操作了。
而且,如果客户端发送的都是读操作请求,那还可以由从库继续提供服务,这在纯读的业务场景下还能被接受,但是,一旦有写操作请求了,按照主从库模式下的读写分离要求
需要由主库来完成写操作。此时,也没有实例可以来服务客户端的写操作请求了,如下图。

在这里插入图片描述

无论是写服务中断,还是从库无法进行数据同步,都是不能接受的。所以,如果主库挂掉了,我们就需要运行一个新主库,比如说把一个从库切换成主库,把它当成主库。这就会涉及到三个问题:

  1. 主库真得挂了吗?
  2. 该选择哪个库为主库?
  3. 怎么把新主库的相关信息通知给从库和客户端呢?

这里就要提到哨兵机制了。在Redis主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效的解决了主从复制模式下故障转移的三个问题。

下面一起来了解下哨兵模式:

哨兵机制的基本流程:
哨兵其实就是一个运行在特殊模式下的Redis进程,主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。

我们先看监控。监控是指哨兵进程在运行时,周期性的给所有的主从库发送PING命令,检查它们是都是否仍在线运行。如果,从库没有在规定时间内响应哨兵PING命令,哨兵就会把它标记为“下线状态”;同样,如果主库也没有在规定时间内响应哨兵的PING命令,哨兵就会判定主库下线,然后开始自动切换主库的流程。

这个流程首先是执行哨兵的第二个任务,选主。主库挂了以后,哨兵就需要多个从库里,按照一定的规则选择一个从库实例,把它最为新的主库。这一步完成后,现在的集群就有了新主库。

然后,哨兵会执行最后一个任务:通知。在执行通知任务时,哨兵会把新主库的连接方式发给其他从库,让他们执行replicaof命令,和新主库建立连接,并进行数据复制。同时,哨兵会把新主库的连接信息通知给客户端,让他们把请求操作发到新主库上。
下图可以展示这第三个任务以及他们的各自目标:
在这里插入图片描述
在这三个任务中,通知任务相对来说比较简单,哨兵只需把新主库信息发给从库和客户端,让它们和新主库建立连接就行,并不涉及决策的逻辑 。但是,在监控和选主这两个任务中,哨兵需要做出两个决策:

  • 在监控任务中,哨兵需要判断主库是否处于线下状态;
  • 在选主任务中,哨兵也要决定选择哪个从库案例作为主库。
    接下来,我们就先说说如何判断主库的下线状态。首先要知道的是,哨兵对主库的下线判断有“主观下线”和“客观下线”两种,那他们为什么会存在两种判断呢?他们的区别和联系是什么呢?

主观下线和客观下线
主关下线:哨兵进程会使用PING命令检测它自己和主、从库的网络连接情况,用来判断实例的状态。如果哨兵发现主库或从库对PING的命令响应超时了,那么,哨兵就会先把他标记为“主观下线”。

如果检测是从库,那么,哨兵简单的把它标记为“主观下线”就可以了,因为从库的下线影响一般不太大,集群的对外服务不会间断。

但是,如果检测是主库,那么,哨兵还不能简单的把它标记为“主管下线”,开启主从切换。因为很有能存在一个这么情况:那就是哨兵误判,其实主库没有故障。可以,一旦启动了主动切换,后续的选主和通知操作都会带来额外的计算和开销。

为了避免这些不必要的开销。我们要特别注意误判的情况。

首先,我们要知道啥叫误判。很简单,就是主库实际并没有下线,并让从库和新主库进行数据同步,这个过程本身就有开销,例如,哨兵要花时间选出新主库,从库也需花时间和新主库同步。而在误判的情况下:主库本身根本就不需要进行切换的,所以这个过程的开销事儿没有价值的,正因为这样,我们需要判断是与否有误判,以及减少误判。

那怎么减少误判呢?在日常生活中,当我们要对一些重要的事情做判断的时候,经常会和家人或朋友一起商量一下,然后再决定。
哨兵机制也是类似的,它**通常会采用多实例组成的集群模式进行部署,这也被称为哨兵集群。**引入多个哨兵实例一起来判断,就可以避免单个哨兵因为自身网络状况不好,而误判主库下线的情况。同时,多个哨兵的网络同时不稳定的概率较小,由他们一起做决策,误判率也能降低。

今天只要先理解哨兵集群在减少误判方面的作用。

在判断主库是否下线时,不能由一个哨兵说了算,只有大多数的哨兵实例,都判断主库已经“主观下线”了,主库才会被标记为“客观下线”,这个叫法也是表明主库下线成为一个客观事实了,这个判断原则就是:少数服从多数。同时,这会进一步触发哨兵开始主从切换流程。

为了方便理解。用两个图来展示一下这里的逻辑。
如图展示,Redis主从集群有一个主库、三个从库,还有三个哨兵实例。在图左,哨兵2判断主库为“主观下线”,但哨兵1和3缺却判断主库是上线状态,此时,主库仍然被判断为处于上线状态;在图片的右边,哨兵1和哨兵2都判断主库为“主库下线,此时即使哨兵3仍然判断主库为上线状态,主库也被标记为“客观下线”了。
在这里插入图片描述
简单来说,“客观下线”的标准就是,当有N个哨兵实例时,最好要有N/2+1个实例判断主库为“主观下线,才能最终判定主库为“客观下线”,这样一来,就可以减少误判的概率,也能避免误判带来的无谓的主从库切换。(当然,有多少个实例做出“主观下线”的判断才可以用,可以有Redis管理员自行设定)
到这里,可以看到,借助于多个哨兵实例的共同判断机制,我们就可以更准确地判断出主库是否处于下线状态。如果主库的确下线了,哨兵就要开始下一个决策过程了,即从许多库中,选出一个从库来做主库。

如何选定新主库?
一般来说,我们哨兵选择新主库的过程称为“筛选+打分”。简单说,我们在多个从库中,先按照一定的筛选条件,把不符合条件的从库去掉。然后我们再按照一定的规则,给剩下的从库逐个打分,将得到最高的从库选为新主库。如下图所示:
在这里插入图片描述
在刚刚的这段话里,需要注意的是两个“一定”,现在,我们要考虑这里的“一定”具体是指什么?
首先来看那筛选的条件:
一般情况下,我们肯定要保证所选的从库仍然在线运行。不过,再选主时从库正常在线,这只能表示从库的现状良好,并不代表它就是最适合做主库的。

设想一下,如果在选主时,一个从库正常运行,我们把它选为新主库开始使用了,可是很快它的网络出了故障,此时我们就要重新选主了。这显然不是我们期望的结果。

所以,在选主时,除了要检查从库的当前在线状态,还要判断它之前的网络连接状态。如果从库总是和主库断连,而且断连的次数超出了一定的阀值,我们就有理由相信,这个从库的网络状态不太好,就可以把这个从库筛掉了。

具体怎么判断呢?你使用配置项down-after-milliseconds*10.其中,down-after-milliseconds是我们认定主从库断连的最大连接超时时间。如果在down-after-milliseconds毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了了,如果发生断连的次数超过了10次,就说明这个从库的网络不稳定,不适合做新主库。
这就过滤掉了不适合做主库的从库。

接下来就要给剩余的从库打分了。我们可以分别按照三个规则依次三轮打分,**这三个规则分别是,从库优先级,从库复制进度,以及库ID号。**只要在某一轮空,有从库得分最高,那么它就是主库了,选主过程到此结束。如果没有出现得分最高的从库,那么就继续进行下一轮。

第一轮:优先级最高的从库得分高
用户可以通过slave-priority配置项,给不同的从库设置不同优先级。比如,你有两个从库,他们的内存大小不一样,你可以手动给内存大的实例设置一个高优先级。在选主时,哨兵会给优先级高的从库打高分,如果有一个从库优先级高,那么它就是新主库了。如果从库的优先级都一样,那么哨兵开始第二轮打分。

第二轮:和旧主库同步程度接近的从库得分高
这个规则的依据是,如果选择和旧主库同步最接近的那个从库作为主库,那么,这个新主库上就有最新的数据。
如何判断从库和旧主库之间的同步进度呢?
之前有介绍过,主从库同步时有个命令传播的过程。在这个过程中,主库会用master_repl_offset记录当前的最新写操作在repl_backlog_buffer中的位置,而从库会用slave_repl-offset这个值记录当前的复制进度。

此时,我们想要的从库,它的slave_repl_offset需要最接近master_repl_offset.。如果在所有从库中,有从库的slave_repl_offset最接近master_repl_offset那么它的得分就是最高,可以作为新主库。

就像下图所示,旧主库的master_repl_offset是1000,从库1、2、3的slave_repl_offset分别是950、990、900,那么。从库2就应该被选为是新主库。
在这里插入图片描述
当然,如果有两个从库的slave_repl_offset值大小是一模一样的(例如,从库1和从库2的slave_repl_offset值都是990),我们需要给他们进行第三次打分。

第三轮:ID号小的从库得分高
每个实例都会有一个ID,这个ID就类似于这里从库的编号。目前,Redis在选主库时,有一个默认的规定:在优先级和复制进度都相同的情况下,ID号最小的从库得分最高,会被选为新主库。

到这儿,新主库就被选出来了,“选主”这个过程就完成了。
我们在回顾一下这个流程。首先,哨兵会按照在线状态,网络状态,筛选过滤一部分不符合要求的从库,然后,依次按照优先级、复制进度、ID号大小再对剩余的从库进行打分,只要有得分最高的从库出现,就把他选为新主库。

小结:
今天主要学习的哨兵机制,他是实现Redis不间断服务的重要保证。具体来说主从集群的数据同步,是数据可靠的基础保障;而在主库发生故障时,自动的主从切换是服务不间断的关键支撑。
Redis的哨兵机制自动完成了以下三大功能,从而实现了主从库的自动切换,可以降低Redis集群的运维开销:

  • 监控主库运行状态,并判断主库是否客观下线。
  • 在主观客观下线后,选取新主库;
  • 选出新主库后,通知从库和客户端
    为了降低误判率,在实际应用时,哨兵机制通常采用多实例的方式进行部署,多个哨兵实例通过少数服从多数的原则,来判断主库是否客观下线。一般来说我们可以部署三个哨兵,如果有两个哨兵认定主观“主观下线,就可以开始切换过程。当然,如果你希望进一步提升判断准确率,也可以在适当增加哨兵个数,比如说使用五个哨兵。”
    但是,使用多个哨兵实例来降低误判率,其实相当于组成了一个哨兵集群:我们也会面临着一些问题:
  • 哨兵集群中有实例挂了,怎么办,会影响主库状态判断和选主吗?
  • 哨兵集群多数实例达成共识,判断出主观“客观下线”后,由哪个实例来执行主从切换呢?
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值