Redis哨兵模式主备切换时数据丢失问题

一、会产生数据丢失的场景

1、异步复制导致的数据丢失

  因为master--》slaver的复制是异步的,所以可能有部分数据还没有复制到slave,master就宕机了,此时master中的数据和slaver中的数据不同步,即数据丢失;

2、脑裂导致数据丢失

  1、什么是脑裂?

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

  2、脑裂引发的数据丢失的问题

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

二、解决方案

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

  •   redis.conf配置如下:
    min-slaves-to-write 1
    min-slaves-max-lag 10
  配置说明 

  该配置必须至少要有1个slave,数据复制和同步延迟不能超过10秒;
  如果说一旦所有的slave,数据复制和同步的延迟度超过了10秒钟,那么master就会拒绝接收任何请求;

作用#

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

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

  • 减少脑裂的数据丢失

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

2、生产者层面:做降级限流

  降级:先将消息写到本地的磁盘中或者放到临时消息队列中,每个10分钟去本地磁盘或者队列里取,来尝试重新发给master;

  限流:在网关减慢请求涌入的速度;

摘抄自(https://www.cnblogs.com/mrmirror/p/13605507.html)感谢!

posted @ 2020-09-03 15:43  whynotbi  阅读(812)  评论(0编辑  收藏  举报