1.1异步复制导致的数据丢失
master node到 slave node的复制是异步的,不能完全保证刚刚接受就写到slave,所以可能有部分数据还没复制到slave,还在内存中,master就宕机了,此时这些部分数据就丢失了,这个是不能避免的,我们把复制的阈值降低,只能减少损失。
1.2 脑裂导致的数据丢失
脑裂,一般是指在高可用系统中,两个节点直接,心跳检测不互通,本来是一个整体,分裂成为两个独立的个体。而且他们互相认为对方有问题,但是实际两个都没有问题,他们就会像脑裂一样,两个东西想控制一个大脑,可能会存在资源争夺,影响两个系统运行,也有可能两个都在同时读写,数据会出错。
一般应付脑裂问题,有可能得几个原因:
- 服务器之间的链路故障,无法通信。
- 网卡或者驱动有问题,ip配置或者冲突等。
- 防火墙把传输挡住了等等。
在redis中也就是,某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着,此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master。这个时候,集群里就会有两个master,也就是所谓的脑裂。
此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master,我们发现了这个脑裂问题之后,需要停掉一个master,选择旧的master。
因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据,那这段时间写到旧的master的数据就相当于丢失了。
2、解决异步复制和脑裂导致的数据丢失
老版本的参数:
min-slaves-to-write 1 min-slaves-max-lag 10
新版本的参数:
min-replicas-to-write 3 min-replicas-max-lag 10
意思是,要求至少有1个slave,数据复制和同步的延迟不能超过10秒,如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了,这时候集群就是有问题的了。客户端当然也应该对redis拒绝写入的情景,做服务降级。
上面两个配置可以减少异步复制和脑裂导致的数据丢失。
-
(1)减少异步复制的数据丢失
有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内。 -
(2)减少脑裂的数据丢失
如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求。这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失。
上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求,因此在脑裂场景下,最多就丢失10秒的数据。