Sentinel是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
首先当Sentinel启动时,需要执行以下步骤:
1)初始化服务器
2)将普通Redis服务器使用的代码替换成Sentinel专用代码
3)初始化Sentinel状态
4)根据给定的配置文件,初始化Sentinel的监视主服务器列表
5)创建连向主服务器的网络连接
Sentinel连接服务器:Sentinel默认会以每10秒一次的频率,通过命令连接向被监视的主服务器发送INFO命令,并通过分析INFO命令的回复来获取主服务器的当前信息和主服务器下从服务器的信息,并建立Sentinel与从服务器的命令连接和订阅连接。
监视同一个服务器的多个Sentinel之间的连接:Sentinel默认情况下以每两秒一次的频率通过命令连接向所有被监视的主从服务器发送PUBLISH命令,当发现新的Sentinel时,会创建一个连向新Sentinel的命令连接,同时新Sentinel也同样会创建连向这个Sentinel的命令连接。
说明:Sentinel在连接主服务器或者从服务器时,会同时创建命令连接和订阅连接,但是在连接其他Sentinel时,只会创建命令连接,而不创建订阅连接;这是因为Sentinel需要通过接收主服务器或者从服务器发来的频道信息来发现未知的新Sentinel,相互已知的Sentinel只要使用命令连接来进行通信就足够了。
检查主观下线:Sentinel默认情况下会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他的Sentinel在内)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。
实例对PING命令的回复可以分为两种情况:
1)有效回复:实例返回+PONG、-LOADING、-MASTERDOWN三种回复的其中一种;
2)无效回复:实例返回除PONG、-LOADING、-MASTERDOWN三种回复之外的其他回复,或者只指定时限内没有返回回复。
Sentinel配置文件中的down_after_milliseconds选项指定了Sentinel判断实例进入主观下线所需的时间长度,不仅用于判断主服务器的主观下线状态,还会被用于判断主服务器属下的所有从服务器;例如
sentinel monitor master 127.0.0.1 6379 2
sentinel down_after_milliseconds master 50000
表示50000毫秒不仅成为Sentinel判断master进入主观下线的标准,还会成为Sentinel判断master属下所有从服务器的主观下线标准;多个Sentinel设置的主观下线时长可能不同。
检查客观下线:当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会通过向同样监视这个主服务器的其他Sentinel发送SENTINEL is-master-down-by-addr命令来查看它们是否也认为主服务器已经进入下线状态(主观下线或者客观下线),当Sentinel从其他Sentinel接收到足够数量的已下线判断后,会将主服务器实例结构flags属性的SRI_O_DOWN标识打开,表示主服务器已经进入客观下线,并对主服务器执行故障转移操作;不同Sentinel判断客观下线的条件数量值可能不同。
当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。
选举领头Sentinel:当一个Sentinel(源Sentinel)向另一个Sentinel(目标Sentinel)发送SENTINEL命令,并且命令中的runid参数不是*符号而是源Sentinel的运行id时,这表示源Sentinel要求目标Sentinel将前者设置为后者的局部领头Sentinel;Sentinel设置局部领头Sentinel的规则是先到先得:最新向目标Sentinel发送设置要求的源Sentinel将成为目标Sentinel的局部领头Sentinel,而之后接收到的所有设置要求都会被目标Sentinel拒绝;领头Sentinel的产生需要半数以上的Sentinel的支持,如果在给定时限内,没有一个Sentinel被选举为领头Sentinel,那么各个Sentinel将在一段时间之后再次进行选举,直到选出领头Sentinel为止。
在选举产生出领头Sentinel之后,领头Sentinel将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:
1)在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。
2)让已下线主服务器属下的所有从服务器改为复制新的主服务器。
3)将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。
故障转移操作第一步要做的就是在已下线主服务器属下的所有从服务器中,挑选出一个状态良好、数据完整的从服务器,然后向这个从服务器发送SLAVEOF no one命令,将这个从服务器转换为主服务器;
挑选规则如下:
1)删除列表中所有处于下线或者断线状态的从服务器,这可以保证列表中剩余的从服务器都是正常在线的。
2)删除列表中所有最近五秒内没有回复过领头Sentinel的INFO命令的从服务器,这可以保证列表中剩余的从服务器都是最近成功进行过通信的。
3)删除所有与已下线主服务器连接断开超过down-after-milliseconds*10毫秒的从服务器:down-after-milliseconds选项指定了判断主服务器下线所需的时间,而删除断开时长超过down-after-milliseconds*10毫秒的从服务器,则可以保证列表中剩余的从服务器都没有过早地与主服务器断开连接,换句话说,列表中剩余的从服务器保存的数据都是比较新的。
之后,领头Sentinel将根据从服务器的优先级,对列表中剩余的从服务器进行排序,并选出其中优先级最高的从服务器。如果有多个具有相同最高优先级的从服务器,那么领头Sentinel将按照从服务器的复制偏移量,对具有相同最高优先级的所有从服务器进行排序,并选出其中偏移量最大的从服务器(复制偏移量最大的从服务器就是保存着最新数据的从服务器)。最后,如果有多个优先级最高、复制偏移量最大的从服务器,那么领头Sentinel将按照运行ID对这些从服务器进行排序,并选出其中运行ID最小的从服务器。
分享学习历程,坚持一周一篇原创,欢迎一起关注学习
我相信坚持一定会有收获