redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;
AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次 redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
如果没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。
RDB 方式,是将redis 某一时刻的数据持久化到磁盘中,是一种快照式的持久化方式。
redis 在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是因为这种特性,让我们随时可以进行备份,因为快照文件总是完整可用的。
对于 RDB 方式,redis 会单独创建(fork) 一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了 redis 极高的性能。
如果需要进行大规模数据的恢复,且对于数据的完整性并不是十分敏感,那么 RDB 方式要比 AOF 方式更加的高效。
虽然 RDB 有不少优点,但是它的缺点也是不容忽视的。如果你对数据的完整性非常敏感,那么RDB 方式就不太适合你。因为即使每5分钟都持久化一次,当redis 故障时,仍然有5分钟的数据丢失。所以,redis还提供了另一种持久化的方式,那就是AOF。
AOF, 英文是 apend only file, 即只允许追加不允许改写的文件。
前面介绍的,AOF 方式就是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,就是这么简单。
通过redis.conf中的 appendonly yes 就可以打开AOF 功能。如果有些操作,redis就会被追加到AOF文件的末尾。
默认的AOF持久化策略是每秒钟fsync(把缓存写到记录中)一次,因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。
如果在追加日志时,恰好遇到磁盘空间满,inode满或断电导致日志写入不完整,也没有关系,redis提供了redis-check-aof 工具,可以用来进行日志修复。
因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了
AOF文件重写 rewrite 机制,即当AOF文件的大小超过所设的阈值时,redis就会启动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文件,这样做是保证原有的AOF文件的可用性,便免在重写过程中出现意外。
当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。
当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中了。
原文:https://www.cnblogs.com/wang-kai-1994/p/10633815.html