Redis 哨兵选举机制

redis集群选举分析

当salve发现自己的master变为FAIL状态时,尝试进行Failover(故障切换)

当存在多个slave的时候,就需要竞争成为master,过程如下

  • (1) slave发现自己的master变为FAIL
  • (2) 将自己记录的集群currentEpock加一,并广播FAILOVER_AUTH_REQUEST信息
  • (3) 其他小集群的master会相应slave的广播消息,首先判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
  • (4) 尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
  • (5) Slave受到超过半数的master的ack就成为新的master
  • (6) Slave广播ping消息通知其他集群节点

Slave节点不是主节点已进入FAIL状态就马上尝试发起选举,而是有一定的延时,一定的延时确保等待FAIL状态在集群中传播。Slave如果立即尝试选举,其它的masters或许尚未意识到FAIL状态,可能会拒绝投票。

延时计算公式:

DELAY = 500ms+random(0~5000ms)+SLAVE_RANK*1000ms

SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已经复制的数据越新。这种方式下,只有最新数据的slave将会首先发起选举。

Redis集群如果发生脑裂,网络分区导致脑裂后多个主节点对外提供写服务,当网络分区回复,会将其中一个主节点变为从节点,变为从节点之后,回从现有主节点复制数据,那原来的数据就会丢失,redis不像zookeeper有过半机制,是通过配置文件的参数

min-replicas-to-write 3

min-replicas-max-lag 10

第一个参数表示连接到master的最少slave数量

第二个参数表示slave连接到master的最大延迟时间

按照上面的配置,要求至少3个slave节点,且数据复制和同步的延迟不能超过10秒,否则的话master就会拒绝写请求,配置了这两个参数之后,如果发生集群脑裂,原先的master节点接收到客户端的写入请求会拒绝,就可以减少数据同步之后的数据丢失。

集群为什么至少三个节点而且推荐节点数为奇数

因为选举需要收到大于master节点总数的一半,若只有两个master节点,其中一个挂了,是选举不出来新的master的
奇数个master节点是为了满足上述要求并且节省资源,三个master节点与四个master节点,当大家都挂了一个master的时候,都能进行选举,当挂了两个的是否都选举不了

哨兵leader选举流程:

1、主观下线

     Sentinel集群的每一个Sentinel节点会定时对redis集群的所有节点发心跳包检测节点是否正常。如果一个节点在down-after-milliseconds时间内没有回复Sentinel节点的心跳包,则该redis节点被该Sentinel节点主观下线。

2、客观下线

当节点被一个Sentinel节点记为主观下线时,并不意味着该节点肯定故障了,还需要Sentinel集群的其他Sentinel节点共同判断为主观下线才行。

该Sentinel节点会询问其他Sentinel节点,如果Sentinel集群中超过quorum数量的Sentinel节点认为该redis节点主观下线,则该redis客观下线。

如果客观下线的redis节点是从节点或者是Sentinel节点,则操作到此为止,没有后续的操作了;如果客观下线的redis节点为主节点,则开始故障转移,从从节点中选举一个节点升级为主节点。

3、Sentinel集群选举Leader

如果需要从redis集群选举一个节点为主节点,首先需要从Sentinel集群中选举一个Sentinel节点作为Leader。

每一个Sentinel节点都可以成为Leader,当一个Sentinel节点确认redis集群的主节点主观下线后,会请求其他Sentinel节点要求将自己选举为Leader。被请求的Sentinel节点如果没有同意过其他Sentinel节点的选举请求,则同意该请求(选举票数+1),否则不同意。

如果一个Sentinel节点获得的选举票数达到Leader最低票数(quorumSentinel节点数/2+1的最大值),则该Sentinel节点选举为Leader;否则重新进行选举。

4、Sentinel Leader决定新主节点

当Sentinel集群选举出Sentinel Leader后,由Sentinel Leader从redis从节点中选择一个redis节点作为主节点:

  • 过滤故障的节点
  • 选择优先级slave-priority最大的从节点作为主节点,如不存在则继续
  • 选择复制偏移量(数据写入量的字节,记录写了多少数据。主服务器会把偏移量同步给从服务器,当主从的偏移量一致,则数据是完全同步)最大的从节点作为主节点,如不存在则继续
  • 选择runid(redis每次启动的时候生成随机的runid作为redis的标识)最小的从节点作为主节点

为什么Sentinel集群至少3节点

一个Sentinel节选举成为Leader的最低票数为quorum和Sentinel节点数/2+1的最大值,如果Sentinel集群只有2个Sentinel节点,则

Sentinel节点数/2 + 1
= 2/2 + 1
= 2

即Leader最低票数至少为2,当该Sentinel集群中由一个Sentinel节点故障后,仅剩的一个Sentinel节点是永远无法成为Leader。

也可以由此公式可以推导出,Sentinel集群允许1个Sentinel节点故障则需要3个节点的集群;允许2个节点故障则需要5个节点集群。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值