《Redis设计与实现》读书笔记(二十七) ——Redis哨兵(sentinel)主服务器下线判断与故障转移

《Redis设计与实现》读书笔记(二十七) ——Redis哨兵(sentinel)主服务器下线判断与故障转移

(原创内容,转载请注明来源,谢谢)

一、主观下线检测

默认情况下,sentinel会每秒1次,向所有它创建的连接实例发送ping命令,包括主从服务器与其他的sentinel。通过实例返回判断是否在线。

有效的回复包括pong、loading和mastdown,无效的回复包括超时的回复以及前三个之外的回复。

在sentinel的配置文件中,down_after_milliseconds指定了sentinel判断主观下线的方式,主服务器连续没给出正确的回复超过这个设定的时间,则表示该主服务器被这个sentinel认定为主观下线。

此时,sentinel会在自身记录主服务器的flags加上一个标签,使得主服务器此时的flags标签变为SRI_MASTER|SRI_S_DOWN。

配置主观下线的down_after_milliseconds,不仅sentinel会对该主服务器进行这样的判断,也同样会将该参数带到该主服务器下的全部从服务器。

另外,不同的sentinel对同一个主服务器,设定的主观下线的值可以不同。每个sentinel会按照自身的配置文件,来判断检测的主服务器是否主观下线。

二、客观下线检测

1、发送检测主观下线命令

当sentinel认定该主服务器主观下线,会同时给其他几个监测此主服务器的sentinel发送命令,确认在其他sentinel处是否也认为该主服务器主观下线。命令格式为:

         sentinel is-master-down-by-addr <ip><port> <current_epoch> <runid>

其中,runid如果是*,表示仅仅检测该主服务器是否主观下线,如果是用sentinel的运行id,则表示选举领头sentinel。

2、接收命令回复

sentinel会收到包含三个参数的multi bulk回复,如下:

1)<down_state>

目标sentinel对该主服务器的检查结果,1表示该sentinel也认为主服务器主观下线,0表示未下线。

2)<leader_runid>

*或者sentinelid,*表示主服务器,sentinelid表示局部主服务器id。

3)<leader_epoch>

领头纪元,用于选举主服务器。

3、客观下线

当回复的sentinel中,认为该主服务器主观下线的个数超过配置文件中设定的quorum的值(包括自身是sentinel),则sentinel认为该主服务器客观下线。

sentinel会给该主服务器加上一个新的flags标签,总体标签变为:SRI_MASTER|SRI_S_DOWN|SRI_O_DOWN。

不同的sentinel可以设置不同的客观下线quorum数量,因此可能部分sentinel认为主服务器客观下线,另一部分认为还没客观下线。

三、选举领头sentinel

当一个主服务器被判定为客观下线,监视该主服务器的各个sentinel,会协商选举一个领头sentinel,对下线主服务器进行故障转移工作。

方式如下:

1)所有在线的sentinel都有参选资格。

2)每次选举领头sentinel,无论是否成功,所有sentinel的配置纪元(epoch)都会加一,这个epoch即计数器。

3)在每一轮的epoch,每个sentinel都有一次机会将某个sentinel设置为局部领头sentinel,设置后在本轮的epoch不可更改。

4)每个发现主服务器客观下线的sentinel都会要求其他的sentinel将自身设置为局部领头。

5)当一个sentinel向另一个sentinel发送sentinelis-master-down-by-addr <ip> <port> <current_epoch> <runid>,其中的runid不是*,而是源sentinel的运行id,则表示源sentinel要求接收者将自身选举为局部领头。

6)设置局部领头的规则是先到先得,先发送的会被设置为领头,后面发送的会被拒绝。

7)目标sentinel接收到第五步的命令后,回复的结果中,<leader_runid>就是源sentinel的运行id,<leader_epoch>是本轮的epoch。

8)源sentinel接收到回复后,会比对runid,如果和自身的一致,则表示目标sentinel已经将源sentinel设置为局部领头。

9)如果某个sentinel被设置为局部领头的数量,超过总sentinel的一半(不含正好一半的情况),则其称为领头sentinel。

10)因为需要半数以上支持,因此每次epoch只会有一个sentinel被选为领头。

11)一定时间内,如果没有选举出领头,则会在一段时间后,再次进行选举。

四、故障转移

选举领头后,领头sentinel将进行故障转移,工作包括:

1)在下线的主服务器对应的从服务器里面,重新选一个主服务器;

2)让其余的从服务器都称为新主服务器的从服务器;

3)把下线的旧主服务器也设置为新主服务器的从服务器,这样其上线后就以从服务器的方式运作。

1、选出新主服务器

sentinel会将下线的主服务器的从服务器列表中,选出一个从服务器,选择规则如下:

1)不考虑已经下线和断线的从服务器,以保证选出的是正常在线的。

2)不考虑最近5秒内没有回复过领头sentinel的info命令的从服务器,以保证选出的是成功通信的。

3)不考虑所有和已下线主服务器断开连接超过down-after-millisecond*10毫秒的从服务器,以保证选出的是数据最新的。

4)将剩余的从服务器,按照从服务器优先级选择主服务器。

5)如果优先级一样,则按照偏移量最大的选择。

6)如果优先级和偏移量都一样的,按照运行ID最小的作为主服务器。

选出主服务器后,sentinel给其发送slaveofno one命令,让其变成主服务器。并且,会每秒一次的频率发送info命令给新主服务器(正常是10秒一次发送info),直到回复中role从slave变成master,表示升级成功。

2、修改其他从服务器的复制目标

即给其余的从服务器,发送slaveof<new_ip> <new_port>,让其余的从服务器重新选则新的主服务器。

3、将旧主服务器变成从服务器

由于其已经下线,无法直接发送slaveof命令,sentinel会将其保存在实例结构里面,待其重新上线,再发送命令。

五、重点回顾

1、sentinel服务器是运行在特殊模式下的redis服务器,其命令表、默认端口都和redis服务器有所不同,只接受7个客户端的命令,默认端口是26379。

2、sentinel会读入用户的主从配置文件,与每个要监视的主服务器创建实例结构,并且创建命令连接和订阅连接,命令连接用来发送ping、publish、info等命令,订阅连接用来监听该主服务器下的所有从服务器的状态。sentinel同样会和从服务器建立这样的两个连接,但是和其他的sentinel只会建立命令连接,没有订阅连接。

3、sentinel通过向监听的主服务器发送info命令,获取并建立相关从服务器的实例结构。info命令通常10秒1次,但是在重新选出的主服务器还未完全从从服务器转成主服务器时,是每秒发送一次info。

4、对于所有监视主从服务器的sentinel,服务器会两秒发送一个__sentinel__:hello频道内容,表示自己还在线。

5、每个sentinel也会从上述频道接收到其他sentinel的信息,并且更新到自身的相应的实例结构中。

6、sentinel每秒1次向所有实例结构(主、从服务器以及其他sentinel服务器)发送ping命令,根据回复判断是否在线,超过规定时间仍是无效回复,则认为该服务器主观下线。

7、当sentinel认为主服务器主观下线,会给其他sentinel发送命令,查询是否其他sentinel也认为其主观下线。当收到的回复中,认为主服务器主观下线的sentinel个数(含自身)超过设置的值,则sentinel认为该主服务器客观下线。

8、判断主服务器客观下线后,sentinel会选出一个领头sentinel,来进行故障转移的工作,选举主要是要拿到超过半数的临时领头。

9、故障转移工作,包括从从服务器中新选出一个主服务器、将其他从服务器复制的对象改为新主服务器、将下线的旧主服务器改为从服务器。

——written by linhxx 2017.09.13

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算

从开发者的角度比较IAAS与PAAS

在我之前的文章中,讨论了云计算背后的基本概念,包括其定义,特性和各种服务模型。在本文中,我将更加详细地讨论服务模型,特别是从开发者的角度来比较IAAS和PAAS...

2616
来自专栏cloudskyme

5招教你把握Java性能监控(转自51testing)

很多开发者觉得自己懂Java编程,事实是大多数开发人员都只领会到了Java平台的皮毛,所学也只够应付工作。作者将深度挖掘Java平台的核心功能,揭示一些鲜为人知...

4197
来自专栏程序员互动联盟

【答疑解惑】Android sdk ndk source的区别

SDK:(software development kit)软件开发工具包。被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发...

2897
来自专栏LanceToBigData

JavaWeb之MVC模式

一、什么是MVC设计模式? MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Mode...

2618
来自专栏吴伟祥

9个基于Java的搜索引擎框架 转

在这个信息相当繁杂的互联网时代,我们已经学会了如何利用搜索引擎这个强大的利器来找寻目标信息,比如你会在Google上搜索情人节如何讨女朋友欢心,你也会在百度上寻...

1824
来自专栏全华班

springcloud学习手册-什么是springcloud?

导读 | springcloud 概念 springboot框架。 了解springcloud前先简单了解一下springboot框架。 springboot是...

3805
来自专栏数据和云

颜值实力派—打造MySQL运行监控环境

作者 | 陈龙,云和恩墨西区工程师,一线服务过金融等行业,精通 oracle 性能优化,故障诊断,特殊恢复领域 。

882
来自专栏互扯程序

SpringBoot 如何在一分钟内整合SSM?

写在前面 前几天看到“互扯程序”技术群(想要入群进行技术讨论请在下方留言)里有人问,什么是SSM?相信99%的人应该知道是什么,那么我给剩下的1%的人再解释一...

4455
来自专栏微服务那些事儿

Spring Cloud 系列-执行器端点(Endpoint)

强推一波:https://segmentfault.com/ls/1650000011386794

2034
来自专栏BeJavaGod

LeeCX - 开源后台管理系统简单介绍

我们在github上开源了一个后台管理系统,使用了前端css框架并且简单的封装了一下,技术的将会不间断更新,详细可以点击https://github.com/l...

3484

扫码关注云+社区