redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。node
RDB,简而言之,就是在不一样的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;redis
AOF,则是换了一个角度来实现持久化,那就是将redis执行过的全部写指令记录下来,在下次redis从新启动时,只要把这些写指令从前到后再重复执行一遍,就能够实现数据恢复了。数据库
其实RDB和AOF两种方式也能够同时使用,在这种状况下,若是redis重启的话,则会优先采用AOF方式来进行数据恢复,这是由于AOF方式的数据恢复完整度更高。缓存
若是你没有数据持久化的需求,也彻底能够关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache同样。app
【聊聊redis持久化 – RDB】工具
RDB方式,是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。性能
redis在进行数据持久化的过程当中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让咱们能够随时来进行备份,由于快照文件老是完整可用的。日志
对于RDB方式,redis会单首创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操做的,这样就确保了redis极高的性能。进程
若是须要进行大规模数据的恢复,且对于数据恢复的完整性不是很是敏感,那RDB方式要比AOF方式更加的高效。内存
虽然RDB有很多优势,但它的缺点也是不容忽视的。若是你对数据的完整性很是敏感,那么RDB方式就不太适合你,由于即便你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。因此,redis还提供了另外一种持久化方式,那就是AOF。
【聊聊redis持久化 – AOF】
AOF,英文是Append Only File,即只容许追加不容许改写的文件。
如前面介绍的,AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,就这么简单。
咱们经过配置redis.conf中的appendonly yes就能够打开AOF功能。若是有写操做(如SET等),redis就会被追加到AOF文件的末尾。
默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),由于在这种状况下,redis仍然能够保持很好的处理性能,即便redis故障,也只会丢失最近1秒钟的数据。
若是在追加日志时,刚好遇到磁盘空间满、inode满或断电等状况致使日志写入不完整,也没有关系,redis提供了redis-check-aof工具,能够用来进行日志修复。
由于采用了追加方式,若是不作任何处理的话,AOF文件会变得愈来愈大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留能够恢复数据的最小指令集。举个例子或许更形象,假如咱们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,彻底能够把这100条指令合并成一条SET指令,这就是重写机制的原理。
在进行AOF重写时,仍然是采用先写临时文件,所有完成后再替换的流程,因此断电、磁盘满等问题都不会影响AOF文件的可用性,这点你们能够放心。
AOF方式的另外一个好处,咱们经过一个“场景再现”来讲明。某同窗在操做redis时,不当心执行了FLUSHALL,致使redis内存中的数据所有被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件尚未被重写(rewrite),咱们就能够用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,而后重启redis,就能够恢复redis的全部数据到FLUSHALL以前的状态了。是否是很神奇,这就是AOF持久化方式的好处之一。可是若是AOF文件已经被重写了,那就没法经过这种方法来恢复数据了。
虽然优势多多,但AOF方式也一样存在缺陷,好比在一样数据规模的状况下,AOF文件要比RDB文件的体积大。并且,AOF方式的恢复速度也要慢于RDB方式。
若是你直接执行BGREWRITEAOF命令,那么redis会生成一个全新的AOF文件,其中便包括了能够恢复现有数据的最少的命令集。
若是运气比较差,AOF文件出现了被写坏的状况,也没必要过度担心,redis并不会贸然加载这个有问题的AOF文件,而是报错退出。这时能够经过如下步骤来修复出错的文件:
1.备份被写坏的AOF文件
2.运行redis-check-aof –fix进行修复
3.用diff -u来看下两个文件的差别,确认问题点
4.重启redis,加载修复后的AOF文件
【聊聊redis持久化 – AOF重写】
AOF重写的内部运行原理,咱们有必要了解一下。
在重写即将开始之际,redis会建立(fork)一个“重写子进程”,这个子进程会首先读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
与此同时,主工做进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样作是保证原有的AOF文件的可用性,避免在重写过程当中出现意外。
当“重写子进程”完成重写工做后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。
当追加结束后,redis就会用新AOF文件来代替旧AOF文件,以后再有新的写指令,就都会追加到新的AOF文件中了。
【聊聊redis持久化 – 如何选择RDB和AOF】
对于咱们应该选择RDB仍是AOF,官方的建议是两个同时使用。这样能够提供更可靠的持久化方案。