为什么持久化?
持久化是Redis保障高可用性的基础。因为Redis是一个内存数据库,它的数据均保存在内存中,如果Redis实例发生宕机,在没有数据备份前提下,你的生产数据将会全部丢失。这时完善的持久化机制,可以把内存中的数据持久化到磁盘上,方便我们进行备份数据和快速恢复数据。
但是持久化就一定能保证数据不丢失吗?
首先我们要了解Redis为了保证高可用性,一般都是从一下几个方面入手的:
- 数据持久化
- 主从复制
- 自动故障恢复
- Redis集群
常见的Redis持久化有两种:(1)RDB快照持久化(2)AOF持久化,区别在于RDB持久化保存完整的数据,AOF缓存的是redis指令(当然我们该可以简化AOF缓存的指令)。缺点也很明显,RDB是某一时刻的数据快照,因此它的数据并不全,生成RDB文件的代价是比较大的,它会消耗大量的CPU和内存资源。RDB持久化适用于主从全量同步数据、数据库备份。AOF适合做增量数据的持久化。Redis启动会优先加载AOF文件进行数据恢复。
单节点模式
单节点模式下只使用RDB持久化,在某一时刻redis宕机,此时的数据并没有来得及进行rdb持久化备份,这就出现了数据丢失的可能。
在Redis单节点模式下,我们可以可以采用RDB+AOF结合使用防止Redis缓存数据丢失,一个进行全量数据备份,一个进行增量操作指令的备份。
Redis集群模式
在Redis集群主从结构下,如果不开启master的持久化,在master意外宕机后,由于数据全在master节点的内存上,在master节点重启后数据将会全部丢失。此时进行主从数据同步操作,将会导致slave从节点的数据也会被master节点的空数据覆盖清理掉。
在master-slave主从模式下master node 必须开启持久化功能来保证数据不丢失。
但是master-node开启持久化并不意味着数据就不会丢失。
数据异步复制时丢失
因为master-slave节点的数据同步是异步的,可能在数据同步完成前master节点发生宕机,此时这部分的数据就意外丢失了。
脑裂时数据丢失
所谓脑裂,是指master节点自己突然脱离正常网络(并没有宕机,还在运行中),与其他的salve节点的连接断开,但哨兵会认为master节点已经宕机,要从slave节点中重新选举新的master节点,这个时候集群中实际存在两个master节点,这就是脑裂。
虽然某一个slave节点被选举为master节点,但是客户端连接的master仍然是旧master节点,数据还是写向旧master节点上,当旧master节点再次恢复后,会作为slave节点挂在新master节点上,旧master节点中的数据会被新master节点上的数据同步清理掉。
解决方案
通过redis.conf 中配置项,设置至少有1个slave,数据复制和同步的延迟不能超过8秒,来减少异步复制和脑裂导致的数据丢失 :
min-slaves-to-write 1
min-slaves-max-lag 8
如果所有的slave节点的数据同步延时都超过8s,master节点拒绝写请求。
这种情况下脑裂也就最多丢失8秒的数据。