Redis学习笔记(十六) Sentinel(哨兵)(下)
消失了一段时间,我又回来啦。不多说,继续把哨兵看完。
检测主观下线状态
默认情况下,Sentinel会以每秒一次的频率向所有与他创建了命令连接的实例(主从服务器以及其他Sentinel)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。
实例对PING命令的回复可以分为两种情况:
有效回复:实例返回+PONG、-LOADING、-MASTERDOWN三种回复的其中一种。
无效回复:实例返回除+PONG、-LOADING、-MASTERDOWN三种回复之外的回复或者规定时间内没有收到任何回复。
指定Sentinel判断实例进入主观回复的时间长度是由Sentinel配置文件中的down-after-milliseconds选项指定的。
如果没有收到master服务器的回复,Sentinel就会将master标记为主观下线,并在master所对应的实例结构的flags属性中打开SRI_S_DOWN标识。
检查客观下线状态
当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的已经下线,它会向同样监视这一主服务器的其他Sentinel进行询问,看他们是否也认为主服务器已经进入下线状态,当Sentinel从其他Sentinel那里接收到足够数量的已下线判断后,Sentinel就会将主服务器判定为科幻下线,并对主服务器执行故障转移操作。
使用 SENTINEL is-master-down-by-addr < ip >< port >< current_epoch >< runid >
当目标Sentinel收到源Sentinel发来的SENTINEL命令后,解析命令中的参数并根据主服务器的ip端口号检查主服务器是否下线,然后回复源Sentinel ,< down_state >< leader_runid >< leader_epoch >
根据其他Sentinel发回的SENTINEL命令回复,统计其他SENTINEL同一主服务器已下线的数量,当这一数量达到配置指定的判断客观下线所需要的数量时,Sentinel会将主服务器实例结构flags属性的SRI_O_DOWN标识打开,标识主服务器已经进入客观下线状态。
选举头领Sentinel
当一个主服务器被判断为客观下线时,监听这个下线主服务器的各个Sentinel会进行协商,选举出一个头领Sentinel,并由头领Sentinel对下线主服务器执行故障转移操作。
所有在线的Sentinel都会有被选为头领Sentinel的资格,换句话说,监视同一个主服务器的多个在线Sentinel中的任何一个都有成为领头Sentinel。
每次进行头领Sentinel选举之后,不论选举是否成功,所有Sentinel的配置纪元的值都会自增一次,配置纪元实际上就是一个计数器。
在一个配置纪元所有Sentinel都有一次将某个Sentinel设置为局部头领Sentinel的机会,并且局部领头一旦设置,在这个配置纪元中就不能再次更改。
每个发现主服务器进入客观下线的Sentinel都会要求其他Sentinel将自己设置为局部头领Sentinel。
当源Sentinel向目标Seninel发送SENTINEL is-master-down-by-addr命令,并且命令中runid不是*而是源Sentinel的运行ID时,这表示源Sentinel要求目标Sentinel将自己设置为局部头领Sentinel。
Sentinel设置局部头领Sentinel的规则是先到先得。
目标Sentinel在接收到SENTINEL is-master-down-by-addr命令之后,将向源Sentinel返回一条命令回复,回复中的leader_runid参数和leader_epoch分别记录了目标Sentinel的局部头领Sentinel的运行ID和配置纪元。
源Sentinel在接收到目标Sentinel返回的命令之后,会检查回复中leader_epoch参数的值和自己的配置纪元是否相同,如果相同,那么源Sentinel继续取出回复中的leader_runid参数,如果leader_runid参数的值和源Sentinel的运行ID一致,那么标识目标Sentinel将源Sentinel设置为局部头领Sentinel。
如果某个Sentinel被半数以上的Sentinel设置为局部领头Sentinel,那么这个Sentinel就称为头领Sentinel。
如果在给定时间限制内,没有一个Sentinel被选举为头领Sentinel,那么各个Sentinel将在一段时间之后再次进行选举,直到选出头领Sentinel。
故障转移
在选举出头领Sentinel之后,头领Sentinel将对这个下线的服务器执行故障转移操作。
在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。
挑选过程:
(1)删除列表中的所有处于下线或者断线状态的从服务器。
(2)删除列表中所有最近5秒内没有服务过头领Sentinel的INFO命令的从服务器。
(3)删除与已下线主服务器连接断开超过down-after-milliseconds * 10 毫秒的从服务器。
(4)按照优先级进行排序,如果优先级最高的有多台,则按照偏移量最大的排序,如果还有多台,则按照运行ID排序取运行ID最小的从服务器。
让已下线主服务器属下的所有从服务器改为复制新的主服务器。
发送命令SLAVEOF < 新主服务器的IP ><新主服务器的PORT>
将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,他就会成为新的主服务器的从服务器。
每天学一点,总会有收获。
说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341