redis之哨兵机制

对于主从库集群模式,当一个从库宕掉后还有主库和其他从库可以使用,但是当主库宕掉后,那就直接会影响到从库的同步,因为从库没有相应的主库可以进行数据复制操作了。

对于客户端的读请求,主库宕掉还可以执行,但是如果对于写操作,则无法执行命令传播,所以接下来就要引入一门技术叫做,哨兵机制。

哨兵机制主要解决了三个问题:

第一就是:解决主库是否真的挂掉问题,不能一个哨兵认为主库挂了,它就真的挂了,需要多个哨兵进行判断才能确定主库真的挂掉了

第二:选择哪一个从库来作为主库。

第三:如何把新主库的信息同步给客户端。

哨兵其实就是一个运行在特殊模式下的 Redis 进程(注意,这里提到的是redis的进程),主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。

哨兵解决这三个问题可以用其三个功能来概括,监控,选主与通知。

对于监控功能:哨兵会周期性的向主从库发送ping命令,检测其是否在线,如果从库没有在规定时间内响应哨兵的 PING 命令,哨兵就会把它标记为“下线状态”;如果主库也没有在规定时间内响应哨兵的 PING 命令,哨兵就会判定主库下线,然后开始进入自动切换主库的流程。即选主流程

主库挂掉后,哨兵就会从多个从库当中选择一个从库来作为主库,这一步完成后,现在的集群里就有了新主库,然后开始进入通知阶段

在执行通知任务时,哨兵会把新主库的连接信息发送给其他从库,让他们执行replaceof命令,和主库进行连接,复制主库的数据,同时,哨兵会把新主库的连接信息通知给客户端,让它们把请求操作发到新主库上。

哨兵对于主库的下线有两种判定方式,分别被主观下线与客观下线。

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

对于从库来说判断其为主观下线,没有影响,但是对于主库来说,如果哨兵直接判断其为主观下线,就进行选主,如果是误判的情况下,就会白白浪费了资源,因为选主过程需要占用网络资源,cpu,还有大量的磁盘操作,误判就是主库实际并没有下线,但是哨兵误以为它下线了。误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下

所以为了降低误判几率,引入了哨兵集群的机制

即通常会采用多实例组成的集群模式进行部署,这也被称为哨兵集群。引入多个哨兵实例一起来判断,就可以避免单个哨兵因为自身网络状况不好,而误判主库下线的情况。同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。

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

这个判断标准就是集群中有N个实例的时候,如果N/2+1个实例判断主库客观下线,则该主库就会被认定成主观下线,然后开始进入选主流程

接下来便是选主流程的详细介绍

选主过程中还需要对于从库进行筛选,筛选掉可能有故障的从库。然后在进行对于从库的打分阶段

筛选条件:第一:判断从库当前在线状态,判断其是否在线  第二还要判断它之前的网络连接状态

如果从库总是和主库断连,而且断连次数超出了一定的阈值,我们就有理由相信,这个从库的网络状况并不是太好,就可以把这个从库筛掉了。具体判断方法可以如下:
使用配置项 down-after-milliseconds * 10。其中,down-after-milliseconds 是我们认定主从库断连的最大连接超时时间。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从库的网络状况不好,不适合作为新主库。

打分判断条件是:

1:从库优先级

2:从库复制进度

3:从库id号

1:

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

2:选择和挂断的主库复制程度最高的从库来作为新的主库,之前介绍到了对于主从复制的过程,主服务器和从服务器通过repl_backblog_buffer 各自维护一个master_repl_offset 和slave_repl_offset变量 ,

主库会用 master_repl_offset 记录当前的最新写操作在 repl_backlog_buffer 中的位置,而从库会用 slave_repl_offset 这个值记录当前的复制进度。此时,我们想要找的从库,它的 slave_repl_offset 需要最接近 master_repl_offset。如果在所有从库中,有从库的 slave_repl_offset 最接近 master_repl_offset,那么它的得分就最高,可以作为新主库。这里我还有一个疑问就是 新选的从库和原主库相比如果仍有丢失,那么对于丢失的那部分数据该怎么办,这个问题应该怎么解决。

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

至此选主流程完成

接下来,就要分析,选主过程是由哪个哨兵实例来执行?哨兵集群中有实例挂了会影响主库状态判断和选主吗?在主从库切换期间,客户端是否还能执行读写操作?

 

 

 

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

 

posted @ 2020-10-15 18:14  xzwcomeon  阅读(209)  评论(0编辑  收藏  举报