redis的持久化
redis是一个高性能的内存数据库,所以可以理解redis的数据都存储在内存中,但如果仅仅存储在内存中,当发生一些意外情况,redis挂了,进程没了,存放在内存中的数据全部都没了,那怎么办?redis的设计者肯定不会有这么大的纰漏,redis有它自己的持久化机制,就是把数据落入磁盘。生产环境中会把磁盘上的数据放入像阿里云ODPS等云存储服务上做一个备份,当redis整个机器挂掉或者损坏,那么我们就可以在另一个机器上启动redis,把备份数据文件拷贝到机器的磁盘上,当redis启动的时候,就会去磁盘上读取数据
1.RDB和AOF两种持久化机制的介绍
RDB持久化机制,对redis中的数据执行周期性的持久化。
AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的时候,通过回放AOF日志中的写入指令来重新构建整个数据集,但是写文件并不是直接写入磁盘,会先写os cache,然后到一定时间再从os cache写道disk file中,比如每隔一秒,调用一次操作系统fsync操作,强制讲os cache中的数据,刷入磁盘文件中。
那么就有一个问题,随着写入命令的不断增加,AOF作为存放每条写入命令的地方,也是会不断膨胀的,不可能让他无限的大下去,所以说,当大到一定程度的时候,AOF就会做rewrite操作;rewrite 会基于当时redis内存中的数据,重新构造一个更小的AOF文件,然后将旧的膨胀很大的文件给删除掉。
怎么来理解redis的rewrite了?我们的redis限定了总内存大小为1G的容量来存放数据,当有了一百万的数据,容量达到了1G,而我们的AOF文件也存放了100万数据相关的写指令,由于redis的内存使用要满了,这个时候会去走内存淘汰策略,把一些数据从内存中删除,腾出一定的空间,比如说,清理掉了50w的数据,到了一定的时间,又写了50w的数据,所以我们的AOF文件已经存了150w数据相关的指令的日志了,变得更加的大了,并且里面有50w的指令日志是不需要的,因为数据已经被删除了,所以这种时候会基于redis当前内存中最新的100w数据来构建新的AOF文件,老的AOF文件就被废弃了,不再使用。
2.两种持久化机制的优劣
RDB持久化机制的优点
(1)RDB会生成多个数据文件,每个数据文件都代表了某个时刻redis的数据,这种多个数据文件的方式,非常适合做冷备,可以将这些数据文件发送到远程的云服务存储上做一个备份。
(2.)RDB对redis对外提供的读写服务影响很小,可以让redis保持高性能,redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化.PS:RDB只会在一定的时间进行磁盘操作,而AOF每次都会写文件,相比较,RDB要快一点。
(3)基于RDB数据文件来重启和回复redis进程,更加快速
RDB持久化机制的缺点:
(1)由于RDB是每隔一段时间生成一份数据文件,所以当redis实例发生故障的时候,最大程度上会损失间隔时间内的数据。
(2)RDB每次fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,甚至数秒
AOF持久化机制的优点:
(1)AOF可以更好的保护数据不丢失,一般AOF会每隔一秒,通过一个后台线程执行一次fsync操作,最多丢失一秒的数据
(2)AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复
(3)AOF日志文件即使过大的时候,出现rewrite操作,也不会影响客户端的读写。因为创建新的日志文件的时候,老的日志文件还是照常写入,当新的merge后的日志文件ready的时候,再交换新老日志文件即可。
(4)AOF日志文件的命令非常可读。比如不小心使用了flushall命令,如果rewrite还没有发生,就可以拷贝AOF文件,把flushall命令删除,再通过此文件来恢复所有数据
AOF持久化的缺点:
(1)同一份数据产生的文件,AOF日志文件会比RDB数据快照文件更大
(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,如果你做成每写入一条数据,fsync一次,那么redis的QPS就会大降
(3)AOF这种基于命令日志/merge/回放的方式,比基于RDB每次持久化一份数据文件的方式,更加的脆弱,容易有bug。
(4)最重要的缺点就是做数据恢复的时候,比较慢。
两者如何选择?
如果仅仅使用RDB,那么你会丢失比较多的数据,只使用AOF的话,没有RDB做冷备更简单,以及恢复速度更快。所以我们综合使用两种持久化机制,用AOF来保证数据不丢失,用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复