高并发高可用复杂系统中的缓存架构(十) redis 主从复制架构高可用,哨兵机制深入介绍

redis 哨兵主备切换的数据丢失问题:异步复制、集群脑裂

两种数据丢失的情况

异步复制导致的数据丢失

 

因为 master -> slave 的复制是异步的,所以可能有部分数据还没复制到 slave,master 就宕机了,此时这些部分数据就丢失了

脑裂导致的数据丢失

 

何为脑裂?如上图由于一个集群中的 master 恰好网络故障,导致与 sentinal 联系不上了,sentinal 把另一个 slave 提升为了 master。此时就存在两个 master了。

当我们发现的时候,停止掉其中的一个 master,手动切换成 slave,当它连接到提升后的 master 的时候,会开始同步数据,那么自己脑裂期间接收的写数据就被丢失了

解决异步复制和脑裂导致的数据丢失

主要通过两个配置参数来解决

  • min-slaves-to-write 1

  • min-slaves-max-lag 10

如上两个配置:要求至少有 1 个 slave,数据复制和同步的延迟不能超过 10 秒,如果超过 1 个 slave,数据复制和同步的延迟都超过了 10 秒钟,那么这个时候,master 就不会再接收任何请求了

此配置保证就算脑裂了,那么最多只能有 10 秒的数据丢失

 

上图说明了脑裂时,master 拒绝写数据的时候,client 可能额外需要做的事情,client 是说使用方,不是 redis 的东西。

下图也是一样的道理,有如上两个参数配置控制的话,脑裂时会减少数据的丢失

 

redis 哨兵的多个核心底层原理的深入解析(包含 slave 选举算法)

 

sdown 和 odown 转换机制

sdown 和 odown 是两种失败状态

  • sdown 是主观宕机

    一个哨兵如果自己觉得一个 master 宕机了,那么就是主观宕机

  • odown 是客观宕机 如果 quorum 数量的哨兵都觉得一个 master 宕机了,那么就是客观宕机

(

quorum的解释如下:

(1)至少多少个哨兵要一致同意,master进程挂掉了,或者slave进程挂掉了,或者要启动一个故障转移操作
(2)quorum是用来识别故障的,真正执行故障转移的时候,还是要在哨兵集群执行选举,选举一个哨兵进程出来执行故障转移操作
(3)假设有5个哨兵,quorum设置了2,那么如果5个哨兵中的2个都认为master挂掉了; 2个哨兵中的一个就会做一个选举,选举一个哨兵出来,执行故障转移; 如果5个哨兵中有3个哨兵都是运行的,那么故障转移就会被允许执行

)

sdown 达成的条件很简单,如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds(在哨兵配置文件中配置的) 指定的毫秒数之后,就主观认为 master 宕机

sdown 到 odown 转换的条件很简单,如果一个哨兵在指定时间内,收到了 quorum 指定数量的其他哨兵也认为那个 master 是 sdown 了,那么就认为是 odown 了,客观认为 master 宕机

哨兵集群的自动发现机制

哨兵互相之间的发现,是通过 redis 的 pub/sub 系统实现的,每个哨兵都会往 __sentinel__:hello 这个 channel 里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在

每隔两秒钟,每个哨兵都会往自己监控的某个 master+slaves 对应的 __sentinel__:hello channel 里发送一个消息,内容是自己的 host、ip和 runid 还有对这个 master 的监控配置

每个哨兵也会去监听自己监控的每个 master+slaves 对应的 __sentinel__:hello channel,然后去感知到同样在监听这个 master+slaves 的其他哨兵的存在

每个哨兵还会跟其他哨兵交换对 master 的监控配置,互相进行监控配置的同步

slave 配置的自动纠正

哨兵会负责自动纠正 slave 的一些配置,比如 slave 如果要成为潜在的 master 候选人,哨兵会确保 slave 在复制现有 master 的数据; 如果 slave 连接到了一个错误的 master 上,比如故障转移之后,那么哨兵会确保它们连接到正确的 master 上

slave->master 选举算法

如果一个 master 被认为 odown 了,而且 majority 哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个 slave 来

会考虑 slave 的一些信息

  • 跟 master 断开连接的时长

  • slave 优先级

  • 复制 offset

  • run id

如果一个 slave 跟 master 断开连接已经超过了 down-after-milliseconds的 10 倍,外加 master 宕机的时长,那么 slave 就被认为不适合选举为 master,公式如下

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

接下来会对 slave 进行排序

  1. 按照 slave 优先级进行排序,slave priority(redis 配置文件中的属性配置,默认为 100) 越低,优先级就越高

  2. 如果 slave priority 相同,那么看 replica offset,哪个 slave 复制了越多的数据,offset 越靠后,优先级就越高

  3. 如果上面两个条件都相同,那么选择一个 run id 比较小的那个 slave

quorum 和 majority

每次一个哨兵要做主备切换,首先需要 quorum 数量的哨兵认为 odown,然后选举出一个哨兵来做切换,这个哨兵还得得到 majority 哨兵的授权,才能正式执行切换

如果 quorum < majority,比如 5 个哨兵,majority=3,quorum=2,那么就 3 个哨兵授权就可以执行切换

但是如果 quorum >= majority,那么必须 quorum 数量的哨兵都授权;比如 5个哨兵,quorum=5,那么必须 5 个哨兵都同意授权,才能执行切换

configuration epoch

哨兵会对一套 redis master+slave 进行监控,有相应的监控的配置

执行切换的那个哨兵,会从要切换到的新 master(salve->master)那里得到一个 configuration epoch,这就是一个 version 号,每次切换的 version 号都必须是唯一的

如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待 failover-timeout 时间,然后接替继续执行切换,此时会重新获取一个新的 configuration epoch,作为新的 version 号

configuraiton 传播

哨兵完成切换之后,会在自己本地更新生成最新的 master 配置,然后同步给其他的哨兵,就是通过之前说的 pub/sub 消息机制

这里之前的 version 号就很重要了,因为各种消息都是通过一个 channel 去发布和监听的,所以一个哨兵完成一次新的切换之后,新的 master 配置是跟着新的 version 号的

其他的哨兵都是根据版本号的大小来更新自己的 master 配置的

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值