redis面试:哨兵模式主从切换数据丢失问题

redis哨兵是怎么工作的

哨兵作用

  • 监控整个主数据库和从数据库,观察它们是否正常运行
  • 当主数据库发生异常时,自动将从数据库升级为主数据库,继续保证整个服务的文档

哨兵是怎样工作的

  • 每隔sentinel以每秒钟一次的频率向他所知的主节点,从节点以及其他sentinel实例发送一个ping命令
  • 如果一个实例(instance)距离最后一次有效恢复PING命令的时间超过 down-after-milliseconds 选项所指定的值,则这个实例会被当前的sentinel标记为主观下线
  • 如果一个主节点被标记为主观下线,则正在监视这个主节点的所有sentinel要以每秒一次的频率确认主节点确定既然进入了主观下线状态
  • 当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认主节点的确进入了主观下线状态,则这个主节点会被标记为客观下线。
  • 当主节点被sentinel标记为客观下线时,sentinel向下线的主节点的所有从节点发送INFO命令的频率会从10s一次改为每秒一次(在一般情况下,每个sentinel会议每10 秒一次的频率向它已知的所有主节点,从节点发送 INFO 命令 )
  • 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会变成主观下线。若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
  • sentinel节点会与其他sentinel节点进行“沟通”,投票选举一个sentinel节点进行故障处理,在从节点中选取一个主节点,其他从节点挂载到新的主节点自动复制新主节点的数据

哨兵的选举过程

  • 第一个发现该master挂了的哨兵,会向每个哨兵发送命令,让对方选举自己成为领头哨兵
  • 其他哨兵如何没有选举过他人,就会将这一票投给第一个发现该master挂了的哨兵
  • 第一个发现该master挂了的哨兵如果发送有超过一般的哨兵投给自己,并且其数量也超过了设定的quoram参数,那么该哨兵就成了领头哨兵
  • 如果多个哨兵同时参与这个选举,那么就会重复该过程,知道选出一个领头哨兵

选出领头哨兵后,就开始了故障修复,会从选出一个从数据库作为新的master

故障转移时会从剩下的slave选举一个新的master,被选举为master的标准是什么?

如果一个master被认为宕机了,而且领头哨兵允许了主从切换,那么某个哨兵就会执行主从切换操作,此时时首先要选举一个slave来,会考虑slave的一些信息

  1. 跟master断开连接的时长

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

  1. slave优先级

按照slave优先级进行排序,slave priority越低,优先级就越高

  1. 复制offset。

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

  1. run id

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

执行切换的那个哨兵在完成故障转移后会做什么

会进行configuration配置信息传播

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

同步配置的时候其他哨兵根据什么更新自己的配置呢?

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

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

这个version就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次新的切换之后,新的master配置是跟着新的version号的,其他的哨兵都是根据版本号的大小来更新自己的master配置的

哨兵模式主从切换数据丢失问题

会产生数据丢失的场景

异步复制导致的数据丢失

因为主节点–> 从节点的复制是异步的,所以可能有部分数据还没有复制到从节点,主节点就宕机了,此时主节点中的数据和从节点中的数据不同步,即数据丢失。

脑裂导致数据丢失

什么是脑裂

当某个主节点所在的机器突然脱离正常的网络,不能与其他的从节点连接,但实际上主节点还在运行着,这时候哨兵就会认为主节点宕机了,然后开启选举,将其他的从节点推举为新节点,这时候集群中就会出现两个主机,这种现象就是脑裂

脑裂引发的数据丢失问题

当一个从节点被推举为新的主节点时,但此时的客户端还没来得及切换到新的主节点,客户端仍然继续向旧的主节点中传输数据,因此当旧的主节点恢复的时候,会成为一个新的主节点,并挂在新的主节点上,自己的数据就会清空,重新从新的主节点复制数据

解决方案

redis层面:通过配置控制同步事件

redis.conf配置如下:

min-slaves-to-write 1
min-slaves-max-lag 10

配置说明:

  • 该配置必须至少有1个从节点,数据复制和同步延迟不能超过10s
  • 如果说一旦所有的从节点,数据复制和同步的延迟超过了10s,那么主节点就会拒绝接收任何请求

作用:

  • 减少异步复制的数据丢失

    • 配置min-slaves-max-lag为10s之后,根据目前主节点–>从节点的复制速度,如果数据同步完成所需要时间超过10s,就会认为主节点未来宕机后损失的数据会很多,主节点就拒绝写入新请求
    • 这样就能将主节点和从节点的数据差控制在10s之内,即使主节点宕机也只是这未复制的10s数据
  • 减少脑裂的数据丢失:

    • 如果不能继续给指定数量的从节点发送数据,而且从节点超过10s没有给自己ack消息,那么就直接拒绝写入新请求,这样脑裂后的旧主节点就不会接收客户端的新数据,也就避免了数据丢失
    • 因此在脑裂场景下,最多就丢失10秒的数据

生产者方面:降级限流

  • 降级:先将消息写到本地磁盘中或者放到临时的消息队列中,每隔10分钟去本地磁盘或者队列中取,来尝试重新发给主节点
  • 限流:在网关减慢请求涌入的速度
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值