数据库与缓存13 分钟阅读更新于 2026-07-30

Redis 持久化怎么选:AOF、RDB 和混合持久化讲清楚

Redis 持久化章节,讲清 AOF 写后日志、三种写回策略、AOF 重写、RDB 快照、save 与 bgsave、混合持久化的取舍。

相关工具

Redis 快,但不能只活在内存里

Redis 的主要数据在内存里,读写很快,但内存有一个天然问题:进程退出、机器重启、故障宕机以后,里面的数据可能就没了。资料 在持久化这一节先回答了一个朴素问题:Redis 如何实现数据不丢失?答案是把数据写到磁盘,重启后再从磁盘恢复。

Redis 常见的持久化方式有三种。AOF 日志会把每一条写操作命令追加到文件里;RDB 快照会把某一时刻的内存数据以二进制形式写入磁盘;混合持久化是 Redis 4.0 以后提供的方式,把 RDB 和 AOF 的优点合在一起。

这三种方式不是谁绝对更好,而是取舍不同。AOF 更关心少丢数据,RDB 更关心恢复速度和文件紧凑,混合持久化试图在两者之间找平衡。理解 Redis 持久化,重点不是背配置项,而是看清楚每种机制到底在牺牲什么、换来什么。

Redis 持久化图解,展示 AOF 日志、RDB 快照和混合持久化的写入、写回、重启恢复流程
Redis 持久化流程总览

AOF 记录写命令,RDB 保存某一刻的内存快照,混合持久化在 AOF 重写时把 RDB 全量数据和 AOF 增量命令合在一个文件里。

AOF:把写命令记下来

AOF 的思路很直接:Redis 每执行一条写操作命令,就把这条命令追加写入 AOF 文件。服务重启时,再读取这个日志文件,把里面的写命令重新执行一遍,数据库就能恢复到接近故障前的状态。

文中特别强调,AOF 是写后日志。所谓写后,就是 Redis 先执行命令,把数据写进内存,然后才记录日志。这一点和 MySQL 常见的写前日志思路不同。Redis 这么做有两个好处:第一,命令已经执行成功了再记录,避免把错误命令写进日志;第二,记录日志发生在命令执行之后,不会阻塞当前写操作本身。

但写后日志也有代价。既然日志是在命令执行后写,如果 Redis 执行完命令、还没来得及把日志真正落到磁盘就宕机,这段数据就可能丢。AOF 的可靠性,很大程度取决于后面的写回策略。

三种写回策略,其实是在选风险

资料 把 AOF 写回策略分成三种:Always、Everysec、No。它们决定的是 AOF 写入文件后,什么时候真正刷到硬盘。这个区别很关键,因为写进内核缓冲区和写到磁盘不是一回事。

Always 是每次写操作命令执行完后,同步把 AOF 日志写回硬盘。它最可靠,但每次写都要等磁盘,性能压力最大。No 是 Redis 不控制写回时机,命令先写到 AOF 文件的内核缓冲区,再由操作系统决定什么时候刷盘。它性能最好,但宕机时可能丢更多数据。

Everysec 是折中方案。每次写操作后先把命令写到内核缓冲区,Redis 大约每秒把缓冲区内容写回硬盘。文中的取舍也很清楚:追求高性能选 No,追求高可靠选 Always,如果允许少量数据丢失,又不希望性能受太大影响,通常选 Everysec。实际业务里,Everysec 也是更常见的选择。

AOF 文件为什么会越来越大

AOF 记录的是写命令。系统运行越久,命令越多,文件自然会越来越大。更麻烦的是,日志里会有很多冗余命令。比如一个 key 被连续修改了十次,真正恢复时只需要最后的结果,但 AOF 文件会把这些历史修改都记下来。

文件变大以后有两个问题。第一,占用磁盘空间越来越多。第二,Redis 重启时需要重放更多命令,恢复会变慢。AOF 的优势是丢失数据少,但如果完全不控制文件体积,它的恢复速度就会被日志长度拖住。

所以 Redis 提供了 AOF 重写机制。重写不是把旧日志逐行压缩一遍,而是直接扫描当前数据库里的键值对,为每个键值对生成能恢复当前状态的写命令,然后写入新的 AOF 文件。等新文件写完,再替换旧文件。这样一来,历史上的重复写入就被合并掉了。

AOF 重写为什么交给子进程

AOF 重写要遍历 Redis server 上所有数据库,还要把键值对转换成写命令并写入磁盘。如果这件事放在主线程里做,Redis 正常处理请求的能力会受到明显影响。文中说,Redis 使用子进程完成 AOF 重写,就是为了避免阻塞主线程,减少对整体性能的影响。

这里还有一个细节:重写期间,主线程不会停下来。用户的新写命令还会继续执行。为了不丢这些增量变化,Redis 会把重写期间的新命令写到缓冲区里。等子进程生成新的 AOF 基础文件后,再把这段增量追加进去,最后用新 AOF 文件替换旧文件。

同时列了几个 AOF 重写触发时机:手动执行 bgrewriteaof;主从复制完成 RDB 文件解析和加载;AOF 重写被设置为待调度执行;AOF 已启用且文件大小比例和绝对值都超过阈值。触发时还要注意,如果已经有 RDB 子进程或 AOF 重写子进程在执行,新的 AOF 重写就无法执行。

RDB:保存某一刻的内存快照

RDB 和 AOF 的思路不一样。AOF 记录命令,RDB 记录数据。文中说,RDB 快照会记录某一个瞬间的内存数据,而且记录的是实际数据。生成快照后,Redis 重启时直接加载这个二进制文件,恢复速度通常比重放大量 AOF 命令更快。

RDB 的优势来自它的紧凑。它保存的是某个时间点的数据结果,不需要把每一次修改过程都记录下来。所以在备份、迁移、主从全量同步这类场景里,RDB 文件很有用。后文讲主从复制时也提到,全量同步使用 RDB 而不是 AOF,一个原因就是 RDB 是经过压缩的二进制数据,文件通常更小。

但 RDB 的问题也清楚:快照之间的数据可能丢。假设你每 5 分钟做一次快照,刚做完快照后 Redis 又运行了 4 分钟,然后机器故障,这 4 分钟里的变化就可能没法靠 RDB 找回来。快照频率太低,丢得多;频率太高,又会影响性能。

save 和 bgsave 差别很大

Redis 提供了两个命令生成 RDB 文件:save 和 bgsave。名字看起来接近,运行方式差很多。文中说明,save 会在主线程生成 RDB 文件。如果写 RDB 文件耗时较长,主线程就会被阻塞,Redis 处理其它命令的能力会下降。

bgsave 则会创建子进程生成 RDB 文件。主线程继续处理客户端请求,子进程负责把快照写到磁盘。实际使用中,bgsave 更适合线上环境,因为它把重活从主线程里挪了出去。

不过 bgsave 也不是没有成本。创建子进程需要 fork,快照写盘会消耗磁盘 I/O,内存数据发生变化时还会涉及写时复制带来的额外内存压力。所以 RDB 的配置不能只想着“多备份更安心”,还要看实例大小、机器内存、磁盘能力和业务写入峰值。

混合持久化:前半段 RDB,后半段 AOF

AOF 丢失数据少,但恢复慢;RDB 恢复快,但快照间隔内可能丢数据。Redis 4.0 提出的混合持久化,就是为了解决这个两难。文中对它的描述很具体:混合持久化工作在 AOF 日志重写过程里。

AOF 重写时,fork 出来的重写子进程会先把和主线程共享的内存数据以 RDB 方式写入 AOF 文件。与此同时,主线程继续处理写命令,这些新命令会进入重写缓冲区。等前面的 RDB 全量数据写完,再把缓冲区里的增量命令以 AOF 方式追加到文件后半段。最后,主进程用这个新文件替换旧 AOF 文件。

所以混合持久化生成的文件很有特点:前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量命令。重启加载时,Redis 先快速加载 RDB 部分,再重放后半段 AOF 命令。这样恢复速度比纯 AOF 快,丢失风险又比单纯依赖低频 RDB 小。

混合持久化也有缺点

混合持久化听起来很理想,但不是没有代价。文中提到两个缺点:AOF 文件可读性变差,兼容性也比较差,Redis 4.0 之前的版本不支持。

可读性变差很好理解。纯 AOF 文件主要是命令日志,人可以打开文件大致看懂里面做了什么;混合持久化的前半段是 RDB 二进制内容,后半段才是 AOF 命令,文件不再像纯文本命令日志那样直观。兼容性问题则来自版本支持,如果你的 Redis 版本较老,或者有跨版本迁移需求,就要格外注意。

从线上使用角度看,混合持久化适合希望兼顾恢复速度和数据安全的场景。但在启用前,仍然要确认 Redis 版本、备份恢复流程、运维工具是否支持。持久化机制不是只看配置能不能打开,还要看出问题时能不能恢复。

怎么选:先问能丢多少数据

选择 Redis 持久化方案时,最先问的不是哪个性能最好,而是业务能接受丢多少数据。如果 Redis 只是缓存,数据可以从 MySQL 或其他系统重建,持久化压力可以小一些。即使 Redis 重启后缓存为空,最多是短时间回源压力变大。

如果 Redis 保存的是计数、队列状态、用户会话、限流状态或某些不容易重建的数据,就要认真考虑 AOF 或混合持久化。想尽量少丢数据,可以用 AOF 的 Everysec 或 Always。Always 更稳,但写入性能成本更高;Everysec 通常在可靠性和性能之间比较均衡。

如果更关心快速恢复和备份迁移,RDB 很有价值。它文件紧凑、加载快,但要接受快照间隔内的数据丢失。很多系统会组合使用:RDB 负责定期快照,AOF 或混合持久化负责降低故障时的数据损失。

别把持久化当成唯一保险

Redis 有持久化,不代表数据就绝对安全。AOF 写回策略、RDB 快照频率、磁盘性能、机器故障方式、文件损坏、主从延迟,都会影响最终能恢复到什么程度。持久化只是本机数据恢复能力的一部分,不等于完整的高可用方案。

如果业务对数据可靠性要求高,还要配合主从复制、哨兵或集群、定期备份、恢复演练。资料 在持久化之后继续讲 Redis 高可用,也说明这两块是连在一起的:持久化解决“重启后从哪里恢复”,高可用解决“服务故障时谁接着提供服务”。

面试或实战里回答 Redis 持久化,可以用一条主线:AOF 记录写命令,数据丢失少但恢复可能慢;RDB 记录某一刻的数据快照,恢复快但快照间隔内可能丢;混合持久化在 AOF 重写时把 RDB 全量和 AOF 增量放到一个文件里,兼顾恢复速度和丢失风险,但可读性、兼容性不如纯 AOF。

常见问题

AOF 为什么叫写后日志?

因为 Redis 是先执行写命令,把数据写入内存,然后再把命令追加到 AOF 日志。这样可以避免记录错误命令,也不会阻塞当前命令执行本身。

AOF 的 Always、Everysec、No 怎么选?

Always 最可靠但性能成本高;No 性能最好但宕机时可能丢更多数据;Everysec 通常是折中方案,允许最多约一秒级数据丢失,同时性能压力较小。

RDB 和 AOF 最大区别是什么?

RDB 保存某一时刻的实际数据快照,恢复快但可能丢快照间隔内的数据;AOF 保存写命令日志,数据丢失少,但文件可能变大,重启重放命令会更慢。

混合持久化文件里到底有什么?

混合持久化文件前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量命令。Redis 重启时先加载 RDB,再重放增量 AOF。

MySQL 与 Redis

继续阅读

返回专题