0%

redis持久化rdb和aof对比

工作中业务写的多了就不怎么关注底层实现了,比如常用的redis缓存,其持久化有两种方式rdb和aof,今天咱们就来聊聊这两中持久化方式的区别!

一、rdb

  1. RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
  2. RDB是一种表示某个即时点的Redis数据的紧凑文件,适合用于备份
  3. RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心
  4. RDB在重启保存了大数据集的实例时比AOF要快
  5. RDB容易造成数据丢失
  6. RDB需要经常调用fork()子进程来持久化到磁盘,数据集很大则fork()比较耗时,重则Redis会停止服务客户端几毫秒甚至一秒。

二、aof

  1. AOF,即Append Only File,以只读的方式追加写命令
  2. AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍
  3. 通过配置redis.conf中的appendonly yes就可以打开AOF功能
  4. 默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),此策略下redis仍然可以保持很好的处理性能,即使出现故障也只会丢失最近1秒钟的数据
  5. AOF遇到磁盘空间满、inode满或断电等情况导致日志写入不完整也没有关系,redis提供了redis-check-aof工具用来进行日志修复
  6. 追加方式如果不做任何处理的话AOF文件会变得越来越大,为此redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集
    • 举个例子:假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理
  7. AOF重写时采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性,重写过程如下:
    • 在重写即将开始之际,redis会创建(fork)一个“重写子进程”,这个子进程会首先读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
    • 与此同时主工作进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
    • 当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。
    • 当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中了。
  8. 灾难恢复的能力
    • 在操作redis时不小心执行了FLUSHALL导致redis内存中的数据全部被清空了,只要redis配置了AOF持久化方式,且AOF文件还没有被重写,此时可以用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,然后重启redis,就可以恢复redis的所有数据到FLUSHALL之前的状态了
  9. AOF文件要比RDB文件的体积大,AOF方式的恢复速度也要慢于RDB方式
  10. 执行BGREWRITEAOF命令,那么redis会生成一个全新的AOF文件,其中便包括了可以恢复现有数据的最少的命令集。
  11. AOF文件被写坏的情况,redis并不会贸然加载这个有问题的AOF文件,而是报错退出,可以通过以下步骤来修复出错的文件:
    • 备份被写坏的AOF文件
    • 运行redis-check-aof –fix进行修复
    • 用diff -u来看下两个文件的差异,确认问题点
    • 重启redis,加载修复后的AOF文件