Redis集群-哨兵模式

Sentinel(哨岗、哨兵)是Redis的主从架构的高可用性解决方案:由一个或多个Sentinel实例(instance)组成的Sentinel系统(system)监视任意多个Redis主节点,以及这些主节点下的所有从节点,当主节点进入下线状态时,自动将该主节点的从节点晋升为主节点,然后由新的主节点继续处理命令请求,从而达到高可用的目的。

在学习Redis的哨兵模式的时候,有几个问题必须要搞清楚:1.主节点是不是真的发生了故障,有没有可能发生误判?如何降低误判?2.主节点挂机,有多个从节点,选择哪一个从节点呢?3.谁负责将从节点变更为主节点?4.主节点信息变更后,如何在集群内保持数据的一致性?5.客户端如何感知到主节点信息的变更?6.故障转移的整体流程是如何进行的?7.哨兵本质上也是一个Redis实例,如果哨兵自己故障了,会如何?

1.主节点故障还是误判?

哨兵对监控主节点会定期的向主节点发送PING命令获取主节点的状态,如果迟迟获取不到该主节点信息就会认为该主节点可能发生了故障【主观下线】,进而通过 sentinel:hello通道向其他哨兵节点发送信息。其他哨兵节点从该通道获取到信息之后,就会向主节点发送PING命令,进行再次验证,如果多个哨兵节点都无法联系到该主节点,该主节点被认定是发生了故障【客观下线】。当然不论是主节点还是从节点,哨兵都会对其进行监控,一旦发现主观下线就标记为SDOWN,主观下线则标记为ODOWN。
主观下线:单个Sentinel 实例对主节点做出的下线判断;
客观下线:多个 Sentinel 实例在对同一个主节点做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的主节点下线判断。 (一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的节点已下线。)

要判断一个主节点是否真的发生了故障,就必须要依靠集群内一定数量的一致认同,这个阈值是由配置文件quorum设定。而如果想要降低除了从网络方面着手(保持网络的畅通),另一个就是增加这个阈值,那么误判的几率就会更小了。但是如果调大客观下线的阈值,有可能会造成故障发现的延迟,从而导致故障时间变长。

2.从节点的选择

当主节点发生了客观下线之后,需要将从节点中选举一个成为新的主节点。如果被选择的从节点本身时故障的,那么进行故障转移是没有实际意义的;如果被选中的从节点数据的同步太小,那么晋升之后就会丢多较多的数据;除此之外,每一个从节点所在的服务器资源可用情况也可能不大一样,如果选择到一些可用资源较差的节点,那么故障转移后Redis的处理能力就会受到较大的影响。基于此,哨兵在选择从节点的时候,必须满足该节点是非故障[非下线]的,优先考虑从节点配置的优先级【slave-priority】;最后考虑复制的进度【slave_repl_offset数据偏移量最大】。

3.从节点变更为主节点

当哨兵发现主节点已经客观下线的时候,哨兵会向其他哨兵节点发起投票,让自己成为这次故障转移的负责人,这个过程也叫作Leader选举。

纪元:每次发生Leader选举,不论是否成功都会自增的计数器,防止选举信息因网络拥塞导致的重放问题;
候选者:所有哨兵节点都可以参与选举;
局部Leader:已获得其他哨兵节点的候选者【哨兵】;
纪元内单票:在单个纪元内,所有的候选者只有一张票,并且只能进行一次投票,先到先得;
竞选过程:1.哨兵节点【也称源节点】发现主节点客观下线,立刻在一个随机的时间内向其他哨兵节点【也称目标节点】发送请求成为Leader;2.目标节点获取到该请求后,查看该主节点转台,如果下线则且没有在当前这个纪元进行投票,则立刻回复源节点的的runid【局部Leader】和当前纪元,如果已投票则直接回复已投票的哨兵节点的runid已经纪元;3.源节点接收到目标节点的恢复,判断runid与纪元是否与自己的runid和纪元一致,如果一致则说明已获得该节点的票数,如果不是则说明未获得该节点的票数;4.当源节点获得到max(quorum, num(sentinel)/2+1)的票数后,则成为当前纪元的Leader。如果在给定的时间内没有一个节点成为Leader,则会开启下一轮的选举,知道选出Leader。

Redis集群-哨兵模式

当Leader被选举出来后,会选择最适当的从节点[非下线、优先级最后、数据同步进度最大]作为新的主节点,向其发送slave on one命令成为主节点,并发送slaveof

4.集群内数据的一致性交互

哨兵中的所有信息并不是由Leader处理完成后在统一更新,而是由每个哨兵在向各个主从内的各个节点信息发送PING命令后获取到的信息来实时更新,以及通过固定的几个频道获取到新的信息从而达到数据的一致。

5.客户端如何感知主节点信息的变更?

对于信息的变更无论是从客户端的角度还是服务的角度,无非就是两种,一种是客户端主动向集群进行轮训,获取到最新的集群信息,另外一种就是等待集群通知客户端集群信息发生变更,这个方式也称之为被动方式。
主动方式:轮训意味着,客户端必须要按照一定的时间间隔不停的向集群发起()信息查询。与集群信息不一致的时间取决于轮训的间隔时间,如果间隔时间设置太小也会导致客户端的频繁轮训,白白消耗资源。
被动方式:由集群内部发出一个集群信息变更事件,客户端在获取到该事件【回调/轮训】后,立刻向集群发起信息的同步,然后再与新主节点建立连接。这种方式的优点是感知比较快。
所以无论是哪种方式都是需要客户端自己做适配

6.故障转移(failover)的整体流程

7.哨兵宕机了,还能不能进行故障转移

要完成故障转移与哨兵集群有关的主要有两点:1.完成对主节点的客观下线;2.进行Leader选举负责完成故障转移。如果这两个点关键点都可以完成,那么故障转移就仍然可以继续完成。实际上要完成对主节点的客观下线,只需要有quorum个哨兵完成对主节点的下线投票,而并非由多少个哨兵决定,所以只要保证哨兵集群中至少有quorum个哨兵就可以完成对主节点的客观下线。另外一个问题,要完成故障转移就必须要完成Leader的选举,而Leader选举的票数为max(quorum, num(sentinel)/2+1),即是说要完成Leader的选举就必须保证能正常工作的哨兵必须是集群中的过半数才行。综上所述,假设现在有7个哨兵组成一个集群,quorum配置为3,如果有4个哨兵发生了故障,则可以完成对主节点的客观下线的判定,但是无法完成故障转移,因为Leader无法被选举出来。
实际上生产环境中会更多的将quorum配置为集群的过半数,如果哨兵集群一般也会控制在3至5个节点。如果需要监控多个主节点,则会考虑使用单独的哨兵进行监控。

Original: https://www.cnblogs.com/zhenjungan/p/16519307.html
Author: zhenjungan
Title: Redis集群-哨兵模式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581874/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球