Redis哨兵机制——高可用性的保证
主要有以下功能
试想一下,如果用来保证redis集群高可用的sentinel是单机,然后sentinel挂了,redis也挂了。这怎么tm的?所以哨兵也是群聚的,所有行动都需要投票决定。
(1)故障转移时,判断一个主节点宕机需要大多数哨兵的同意,这就涉及到分布式选举的问题。
(2)即使某些前哨淋巴结挂机,前哨丛仍能正常工作。
(1)sentinel至少需要3个实例来确保其健壮性。
(2)Sentinel+redis的主从部署架构不会保证零数据丢失,只是保证redis集群的高可用性。
我们在多台机器上部署哨兵,它们需要协作完成一项任务,于是形成了“分布式系统”。
在分布式系统领域,一个问题上有多少个节点达到一个* * *知识算法叫做* * *知识算法。
在这个场景中,多个哨兵互相协商选出一个被所有人认可的领袖,这是通过使用* * *知识算法完成的。
这种算法还规定了节点数必须是奇数,可以保证即使一个节点失效,系统中仍有一半以上的节点处于正常状态,仍能提供正确的结果,也就是说这种算法也兼容故障节点的情况。
分布式系统领域有很多* * *知识算法,比如Paxos,Raft,还有哨兵选举领袖的场景。使用Raft ***知识算法是因为它足够简单,容易实现。
Sdown和odown两种故障状态。
sdown的条件很简单。如果sentry ping主服务器超过is-master-down-after-milliseconds(可在sentry配置文件中配置)指定的毫秒数,则主观上认为主服务器已关闭。
sdown到odown转换的条件非常简单。如果一个哨兵在规定的时间内收到quorum发来的规定数量的其他哨兵,认为主人是sdown,那么就认为是odown,客观上认为主人是down。
哨兵通过redis的发布/订阅系统找到彼此。每个哨兵都会向频道__sentinel__:hello发送一条消息。这时,其他所有的哨兵都能消耗这条信息,感知到其他哨兵的存在。
每两秒钟,每个哨兵都会向自己正在监控的一个主+从对应的__sentinel__:hello通道发送一条消息,包括自己的主机、ip和runid以及这个主的监控配置。
每个哨兵还会监听他所监控的每个主人+奴隶对应的__sentinel__:hello频道,然后感知到其他哨兵也在监听这个主人+奴隶的存在。
每个岗哨还会与其他岗哨交换master的监控配置,并相互同步监控配置。
哨兵将负责自动纠正一些配置的奴隶。例如,如果主设备关闭,并且选择了新的主设备,则原来的从设备连接到了错误的主设备。故障转移后,哨兵将确保它们连接到正确的主服务器。
如果一个主设备被认为是odown,并且多数哨兵(most sentinels)允许主备切换,那么一个哨兵将执行主备切换操作,此时必须先选举一个从设备。
选择新的主节点会考虑从节点的一些信息。
(1)先过滤掉与主断开时间太长的,再选择。
(2)从设备的优先级
(3)复制偏移
(4)运行id
首先,如果一个从机与主机的断开次数超过了10次,再加上主机的停机时间,那么这个从机就被认为不适合被选为主机——(down-after-milli relations * 10)+milli relations _ master _ is _ in _。
移除断开时间过长的节点,然后对从节点进行排序。
(1)按从属优先级排序。从机优先级越低,优先级越高。
(2)如果从优先级相同,那么看副本偏移量,哪个从拷贝的数据多,偏移量越晚优先级越高。
(3)如果上述两个条件相同,则选择运行id较小的从机。
有一个基本原理,推断从机有最新数据;
法定人数:达到odwn的条件。
多数:主备切换的情况。
每次哨兵要进行主备切换,首先法定人数的哨兵数量需要想odown,然后选出一个哨兵进行切换,并且这个哨兵要得到多数哨兵的授权才能正式进行切换。
哨兵会监控一套redis主+从,有相应的监控配置。配置时期是一个版本号,每个交换机的版本号必须是唯一的。(配置时期用于比较一个节点的配置是否是最新的。见第8点。)
执行切换的哨兵会从新主切换(保存->;Master)获取一个配置epoch,哨兵获取后,进行主从节点切换。
如果第一个选择的哨兵无法切换,其他哨兵将等待故障转移超时时间,然后接管并继续执行切换。此时,将重新获取新的配置时期作为新的版本号。
哨兵完成切换后,会在本地更新生成最新的主配置,然后与其他哨兵同步,也就是通过前面提到的pub/sub消息机制。
之前的版本号在这里很重要,因为各种消息都是通过一个通道发布和监控的,所以一个哨兵完成一个新的切换后,新的主配置后面跟着新的版本号。
其他哨兵根据版本号的大小更新自己的主配置(如果发现自己的版本落后于得到的版本,就会更新自己的主配置)。