目录
Redis 是一个键值对数据库服务器,服务器中通常包含着任意个非空数据库,而每个非空数据库中有可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及它们的键值对统称数据库状态。
Redis 是内存数据库,它将自己的数据库状态储存在内存里,如果不想办法将储存在内存中的数据库状态保存到磁盘里,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。为了解这个问题,Redis 提供了两种持久化方式—— RDB(Redis DataBase) 和 AOF(Append Only File) ,这可以将 Redis 在内存中的数据库状态保存到磁盘里。
前面两篇文章已经详细介绍了 RDB持久化详解 和 AOF 持久化详解,现在对比一下二者各自的优缺点以及混合持久化。
1. RDB 持久化的优缺点
优点:
- RDB 文件紧凑,全量备份,非常适合用于进行备份和灾难恢复;
- 生成 RDB 文件的时候,Redis 主进程会 fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作;
- RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
全量数据快照,文件小,恢复快。
缺点:
RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。当进行快照持久化时,会开启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据。
无法保证最近一次快照后的数据。
2. AOF 持久化的优缺点
优点:
- AOF 可以更好的保护数据不丢失,一般 AOF 会每隔1秒,通过一个后台线程执行一次 fsync 操作,最多丢失1秒钟的数据;
- AOF 文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损;
- AOF 文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
- AOF 文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用 flushall 命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝 AOF 文件,将最后一条 flushall 命令给删了,然后再将该 AOF 文件放回去,就可以通过恢复机制,自动恢复所有数据。
可读性较高,适合保存增量数据,数据不易丢失
缺点:
- 对于同一份数据来说,AOF 文件通常比 RDB 数据快照文件更大;
- AOF 开启后,支持的写 QPS 会比 RDB 支持的写 QPS 低,因为 AOF 一般会配置成每秒 fsync 一次日志文件,当然,每秒一次 fsync,性能也还是很高的;
- 以前 AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。
文件体积大,恢复时间长。
命令 | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 容易丢失数据 | 根据 fsync 策略决定 |
轻重 | 重 | 轻 |
3. 混合持久化
重启 Redis 时,我们很少使用 RDB 来恢复数据库状态,因为会丢失大量数据。我们通常使用 AOF 日志重写,但是 AOF 重写性能相对 RDB 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。
Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。
通过 redis.conf文件中的 aof-use-rdb-preamble yes 来开启混合持久化,然后重启 Redis 服务。
混合持久化同样也是通过 BGREWRITEAOF 完成的,不同的是当开启混合持久化时,fork 出的子进程先将共享的内存副本全量的以RDB方式写入 AOF 文件,然后在将 aof_rewrite_buf 重写缓冲区的增量命令以 AOF 方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。简单的说:新的AOF文件前半段是 RDB 格式的全量数据后半段是 AOF 格式的增量数据。(关于AOF 重写可以参考 详见 Redis 持久化——AOF 详解 中的章节)
也就是说在原来 AOF 重写之前,先将内存 RDB 快照的内容也写入到新的 AOF 文件中,然后再进行 AOF 重写,最后原子的覆盖旧的 AOF 文件。
![](https://i-blog.csdnimg.cn/blog_migrate/cce3f5cb927e0310d429263ad0d9b87c.png)
AOF根据配置规则在后台自动重写 AOF 文件,也可以人为执行命令 BGREWRITEAOF 重写 AOF。于是在 Redis 重启的时候,先加载 RDB 的内容,然后再执行 AOF 命令部分达到 Redis 数据重放的目的,这样先重写 RDB 到内存,然后在重写 AOF 到内存,重启效率高,还能减少数据的丢失。
缺点:兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该 AOF 文件,同时由于前部分是 RDB 格式,阅读性较差。
参考:
https://baijiahao.baidu.com/s?id=1654694618189745916&wfr=spider&for=pc
https://blog.csdn.net/xinbumi/article/details/89742930