尽管 RDB 比 AOF 的数据恢复速度快,但是快照的频率不好把握:
- 频率太低,两次快照间发生宕机,会带来较多的数据丢失
- 频率太高,频繁的磁盘 I/O 以及创建子进程会造成额外的性能损失
自 Redis 4.0,提出了一个混合使用 AOF 日志和内存快照的方法
开启混合持久化
1 | aof-use-rdb-preamble yes |
混合持久化过程
混合持久化同样也是通过 bgrewriteaof
完成的,不同的是当开启混合持久化时,fork 出的子进程先将共享的内存副本全量的以 RDB 方式写入 aof 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区的增量命令以 AOF 方式写入到文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件
如此,避免了频繁快照时 fork 对主线程的影响,以及 RDB 过程发生宕机可能丢失的数据会更少。而且,AOF 日志也只用记录两次快照间的操作,不需要记录所有操作了,因此,就不会出现文件过大的情况了,也可以避免重写开销
数据恢复
开启混合持久化后,Redis 启动时依然是优先加载 aof 文件,但存在两种情况:
- 开头是 rdb 格式:先加载 rdb 内容,再加载剩余的 aof
- 开头不是 rdb 格式:直接加载整个 aof 文件
持久化总结
RDB
优点:
RDB 是一个非常紧凑(compact)的文件,体积小,因此在传输速度上比较快,因此适合灾难恢复
RDB 可以最大化 Redis 的性能,父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作
RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
缺点:
RDB 是一个快照过程,无法完整的保存所以数据,尤其在数据量比较大时候,一旦出现故障丢失的数据将更多
当 Redis 中数据集比较大时候,由于 RDB 需要对数据进行完成拷贝并生成快照文件,fork 的子进程会耗CPU,并且数据越大,RDB 快照生成会越耗时
RDB文件是特定的格式,阅读性差,由于格式固定,可能存在不兼容情况
AOF
优点:
数据更完整,秒级数据丢失(取决于设置 fsync 策略)
兼容性较高,由于是基于 Redis 通讯协议而形成的命令追加方式,无论何种版本的 Redis 都兼容,再者 aof 文件是明文的,可阅读性较好
缺点:
数据文件体积较大,即使有重写机制,但是在相同的数据集情况下,AOF 文件通常比 RDB 文件大
恢复速度较慢,特别在数据量大时候,AOF 恢复速度明显慢于 RDB
由于频繁地将命令同步到文件中,AOF 对性能的影响相对 RDB 较大,但是对于我们来说是可以接受的