前面已将介绍完了,Sentinel之间通过发送信息给被监听的服务器,发现其他监视同一台服务器的Sentinel,然后对其进行实例化,然后保存在Master里面对应服务器实例的sentinel字典中去,然后如果是新来的Sentinel,还要进行命令连接。
下面就来介绍一下Sentinel是怎么判断被监视的服务器下线了的
检测主观下线状态
在默认情况下,Sentinel会以每一秒的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他Sentinel在内)发送Ping命令,并且通过实例返回的Ping命令回复来判断实例是否在线
命令连接的实例对Ping的回复又分为下面两类
- 有效回复:回复返回+Pong、-LOADING、-MASTERDOWN三种回复之一
- 无效回复:实例返回除了有效回复之外的回复,或者在指定时限内没有返回任何的回复
Sentinel的配置文件中有一个down-after-milliseconds选项,该选项指定了如果被监视的服务器多少毫秒内,没有返回有效恢复给Sentinel,那么Sentinel就会修改这个实例对应的实例结构,具体的修改就是将实力结构里面的flags属性改为SRI_S_DOWN标识(正常的服务器为SRI_MASTER,注意这里为S_DOWN,也就是Subjectly Down),以此来表示这个实例进入了主观下线状态。
注意:在down-after-milliseconds选项指定的毫秒内,Sentinel会一直以每一秒的效率给监视的服务器发送Ping命令,如果超过了指定毫秒都没有收到,就标记为主观下线
主观下线时长选项的作用范围
在Sentinel配置文件中设置的down-after-milliseconds选项,不仅仅只会作用与被监听的主服务器,对于主服务器属下的所有从服务器,以及所有监视同一台主服务器的Sentinel,也是按照一样的规则去判断主观下线
监视同一台主服务器的多个Sentinel设置的主观下线时间可能不同
如果监视同一台主服务器的多个Sentinel设置的主观下线时间可能是不同的,只不过这个是互相独立的,Sentinel自己对监视的服务器认定为主观下线,所以是可能存在一台Sentinel认定该服务器主观下线,而另一台Sentinel认定它还没下线,只有同时满足两台Sentinel的主观下线规则,才会都认定为主观下线。
检测客观下线状态
判定一个服务器到底是否真的下线,取决于客观下线状态,当一个Sentinel认定监视的服务器为主观下线之后,为了确认这个主服务器是否真的下线了,他会向同样监视这一主服务器的其他Sentinel进行询问,看他们是否也认为主服务器进入了下线状态(可能是主观下线,也可能是客观下线),如果是客观下线,就进行故障转移,如果是主观下线,等接收到足够数量的Sentinel认为是主观下线,也会进行故障转移,如果数量不够,就不进行。
而这个数量是由配置文件决定的,配置文件里面进行配置监视服务器的命令为
sentinel monitor <服务器名字> <ip地址> <端口号> <哨兵数量>
这里的哨兵数量,其实就是,多少个Sentinel认为主观下线,那么该服务器就会被认定为客观下线
发送SENTINEL is-master-down-by-addr命令
该命令是Sentinel通过与其他Sentinel的命令连接进行发送的
Sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
下面说一下这几个参数的是什么含义
参数 | 意义 |
---|---|
ip | 被Sentinel判断为主观下线的主服务器IP地址 |
port | 被Sentinel判断为主观下线的主服务器的端口 |
current_epoch | Sentinel当前的配置纪元,用于选举领头Sentinel的 |
runid | runid可以为*或者是Sentinel自己的runid,如果是 *符号代表命令仅仅用于检测主服务器的客观下线状态(即判断该主服务器是不是为客观下线状态),如果是Sentinel自己的运行id则用于选举领头的Sentinel |
领头的Sentinel下面再说有什么作用
接收SENTINEL is-master-down-by-addr命令
当一个Sentinel(称为目标Sentinel)收到了源Sentinel发来的该命令,会分析传来的各个参数,并且根据其中的主服务器的IP和端口号,去检查主服务器是否已下线(也是通过Ping命令),然后向源Sentinel返回一条包含三个参数的Multi Bulk回复作为响应回复给源Sentinel
这三个参数分别如下
- down _state
- leader_runid
- leader_epoch
这三个参数的意义如下
参数 | 意义 |
---|---|
down_state | 返回目标Sentinel对主服务器的检查结果,1代表认为已下线,0代表认为服务器未下线 |
leader_runid | 可以是*符号,也可以是目标Sentinel的局部领头的运行ID, *符号命令仅仅用于来检测主服务器的下线状态,如果是运行ID,则用于选举领头Sentinel |
leader_epoch | 目标Sentinel的局部领头的配置纪元,也是用来选举领头的Sentinel,仅仅在leader_runid不为*符号时有效 |
接收Sentinel is-master-down-by-addr命令回复
根据其他Sentinel的回复,Sentinel将会去统计其他同意主服务器已经下线的Sentinel数量,当这一数量达到了配置指定的判断客观下线所需的数量时,Sentinel将会令主服务器实力结构的flags属性的SRI_O_DOWN表示打开,表示主服务器已经进入了客观下线状态(s_down代表主观下线,o_down代表客观下线)
客观下线状态的判断条件
当认为主服务器已经进入下线之状态的Sentinel数量,超过了Sentinel配置中设置的quorum参数的值,也就是前面命令所提到的那个选项,那么该Sentinel就会认为主服务器已经进入了客观下线状态。
不同Sentinel判断客观下线的条件可能不同
注意这里,每台Sentinel配置指定数量也是可以不同的,所以一台Sentinel认为服务器客观下线,可能其他Sentinel并不会这样认为。
但即使不这么认为,只要有一个Sentinel认为客观下线了,就会去将这个服务器踢出去