Redis集群-哨兵模式原理(Sentinel)
Posted IT-老牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis集群-哨兵模式原理(Sentinel)相关的知识,希望对你有一定的参考价值。
文章目录
1.哨兵模式(Sentinel)
哨兵模式是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以同时监控任意多个主服务器,以及每个主服务器下的所有从服务器。在监视到主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
示意图
- 双环代表主服务器server1
- 单环代表三个从服务器server2、server3、server4
- server2、server3、server4三个从服务器正在复制主服务器server1,而sentinel系统正在监听所有四个服务器
可以看出哨兵模式就是在主从复制模式之上添加了哨兵系统,从而实现故障的自动转移
故障转移
如上图16-3所示,主服务server1挂掉了,处于下线状态,那么server2、server3、server4对主服务器的复制操作将被终止,并且隔一段时间sentinel系统也会察觉到server1的下线,下面先说一下故障转移的流程:
- Sentinel系统会挑选server1属下的其中一个从服务器,并选中的从服务器升级为新的主服务器
- Sentinel系统会向server1属下的所有从服务器发送新的复制命令,让他们成为新的主服务器的从服务器,当所有从服务器都开始复制新的主服务器时,故障转移操作执行完毕
- Sentinel系统还会继续监听已下线的server1,如果它重新上线时,会将它设置为新的主服务器的从服务器
2.Sentinel系统与各个节点的通讯
2.2.1.Sentinel如何判断主服务器下线
主观下线
在默认情况下,Sentinel系统会以每秒一次的频率向所有与它创建了命令连接的实例发送PING命令,并通过实例返回的结果来判断实例是否在线。
如果一个实例在down-after-milliseconds毫秒内(默认30s),连续向Sentinel返回无效回复,那该Sentinel就会将其标记为主观下线状态。
Sentinal配置文件中的down-after-milliseconds
选项指定了Sentinel判断实例进入主观下线所需的时间长度
客观下线
当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他Sentinel进行询问,看它们是否也认为主服务器已经是下线状态(可以是主观下线或客观下线),当Sentinel从其他Sentinel那里接受到足够数量的已下线判断之后,Sentinel就会将从服务器判定为客观下线,并对主服务器开始执行故障转移操作。
客观下线状态的判断条件:当认为主服务器已经进入下线状态的Sentinel的数量,超过Sentinel配置中设置的quorum
参数的值,那么该Sentinel就会认为主服务器已经进入客观下线状态。
上面配置的含义:包括当前Sentinel在内,只要总共有两个Sentinel认为主服务器已经下线,那么当前Sentinel就将主服务器判断为客观下线。
当Sentinel将一个主服务器判断为主观下线后,它会向同样监视该主服务器的其他Sentinel进行询问,看它们是否同意这个主服务器已经进入主观下线状态。
3 .Sentinel如何判断主服务器下线
3.1.选举领头Sentinel
当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。
选举领头Sentinel的规则:
1.所有在线的Sentinel都有被选为领头Sentinel的资格,换句话说,监视同一个主服务器的 多个在线Sentinel中的任意一个都有可能成为领头Sentinel
2.每次进行领头Sentinel选举之后,不论选举是否成功,所有Sentinel的配置纪元 (configuration epoch)的值都会自增一次。 配置纪元实际上就是一个计数器,并没有什么特 别的。
3.在一个配置纪元里面, 所有Sentinel都有一次将某个Sentinel设置为局部领头Sentinel的机会 并且局部领头一旦设置,在这个配置每个发现主服务器进入客观下线的Sentinel都会要求其他Sentinel将自己设置为局部领头Sentinel。
4.当一个Sentinel(源Sentinel)向另一个Sentinel(目标Sentinel)发送SENTINEL ismaster-down-by-addr命令,并且命令中的runid参数不是*符号而是源Sentinel的运行ID时,这表示源Sentinel要求目标Sentinel将前者设置为后者的局部领头Sentinel
5.Sentinel设置局部领头Sentinel的规则是先到先得:最先向目标Sentinel发送设置要求的源Sentinel将成为目标Sentinel的局部领头Sentinel,而之后接收到的所有设置要求都会被目标Sentinel拒绝
6.目标Sentinel在接收到SENTINEL is-master-down-by-addr命令之后,将向源Sentinel返回 一条命令回复,回复中的leader_runid参数和leader_epoch参数分别记录了目标Sentinel的局部领头Sentinel的运行ID和配置纪元
7.源Sentinel在接收到目标Sentinel返回的命令回复之后,会检查回复中leader_epoch参数 的值和自己的配置纪元是否相同,如果相同的话,那么源Sentinel继续取出回复中的 leader_runid参数, 如果leader_runid参数的值和源Sentinel的运行ID一致,那么表示目标 Sentinel将源Sentinel设置成了局部领头Sentinel
8.如果有某个Sentinel被半数以上的Sentinel设置成了局部领头Sentinel,那么这个Sentinel成 为领头Sentinel。举个例子,在一个由10个Sentinel组成的Sentinel系统里面,只要有大于等于 10/2+1=6个Sentinel将某个Sentinel设置为局部领头Sentinel,那么被设置的那个Sentinel就会成 为领头Sentine
9.因为领头Sentinel的产生需要半数以上Sentinel的支持,并且每个Sentinel在每个配置纪元里面只能设置一次局部领头Sentinel,所以在一个配置纪元里面,只会出现一个领头 Sentinel
10.如果在给定时限内,没有一个Sentinel被选举为领头Sentinel,那么各个Sentinel将在一段时间之后再次进行选举,直到选出领头Sentinel为止
演示案例
假设现在有三个Sentinel
正在监视同一个主服务器, 并且这三个Sentinel
之前已经通过 SENTINEL is-master-down-by -addr
命令确认主服务器进入了客观下线状态,如下图所示
那么为了选出领头Sentinel,三个Sentinel将再次向其他Sentinel发送SENTINEL is-masterdown-by-addr
命令,如下图所示
和检测客观下线状态时发送的SENTINEL is-master-down-by-addr
命令不同,Sentinel这次发送的命令会带有Sentinel自己的运行ID,
例如:
如果接收到这个命令的Sentinel还没有设置局部领头Sentinel的话,它就会将运行ID为e955b4c85598ef5b5f055bc7ebfd5e828dbed4fa的Sentinel设置为自己的局部领头Sentinel,并返 回类似以下的命令回复:
然后接收到命令回复的Sentinel就可以根据这一回复,统计出有多少个Sentinel将自己设置成了局部领头Sentinel
根据命令请求发送的先后顺序不同,可能会有某个Sentinel的SENTINEL is-master-downby -addr命令比起其他Sentinel发送的相同命令都更快到达,并最终胜出领头Sentinel的选举, 然后这个领头Sentinel就可以开始对主服务器执行故障转移操作了。
3.2.新主服务器的选举&故障转移
选举好领头Sentinel之后,领头Sentinel将对已下线的服务器执行故障转移操作。
第一步:首先会从已下线主服务器(server1)属下所有的从服务器中挑选一个状态良好、数据完整的从服务器,并发送SLAVE no one
命令。
第二步:此时领头Sentinel会以每秒一次的频率(平时十秒一次)向被升级的从服务器(server2)发送INFO
命令并观察返回的role是否已经变成了master,变成master说明升级成功。
第三步:领头Sentinel向已下线主服务器(server1)的两个从服务器(server3、server4)发送SLAVEOF
命令,让他们复制新的主服务器(server2)。
第四步:当server1重新上线时,Sentinel就会向它发送SLAVEOF
命令,让它成为新主服务器(server2)的从服务器。
至此,整个故障转移就完成了。
以上是关于Redis集群-哨兵模式原理(Sentinel)的主要内容,如果未能解决你的问题,请参考以下文章