返回首页

Redis核心2.1:RDB 与 AOF持久化详解

适用版本:Redis 7.2.x

Redis 是典型的内存数据库,数据主要保存在内存中,因此一旦进程退出、机器重启,或者发生异常宕机,内存数据就可能丢失。为了让 Redis 既有高性能,又能在一定程度上保障数据安全,持久化机制就变得非常关键。

本文聚焦 Redis 中最核心的两种持久化方式:RDBAOF。如果你刚开始学习 Redis,可以先把它理解为两个问题:

  • Redis 如何把内存里的数据落到磁盘?
  • Redis 重启后如何把磁盘中的数据重新恢复出来?

一、什么是 Redis 持久化

Redis 持久化,就是把当前内存中的数据状态保存到磁盘文件中。这样即使 Redis 进程退出,也可以在下次启动时重新加载数据。

Redis 主要有两套持久化机制:

  • RDB(Redis Database):按某个时间点把内存数据做成快照保存下来。
  • AOF(Append Only File):把每一次写命令按追加日志的方式记录下来,重启时重新执行这些命令来恢复数据。

很多初学者会问:

既然有两种持久化方式,是不是二选一就行?

答案是:可以二选一,但生产环境更常见的是组合使用。因为它们各有优缺点,组合起来更稳妥。


二、RDB:快照式持久化

1. RDB 的核心概念

RDB 的思路非常直接:

在某个时刻,把 Redis 当前所有数据做一次“全量快照”,写入 .rdb 文件。等 Redis 重启时,再从这个文件中把数据读回来。

可以把它理解成“给 Redis 当前内存拍一张照片”。

RDB 的特点:

  • 文件体积通常较小,适合备份和数据传输
  • 恢复速度通常比 AOF 更快
  • 对运行时性能影响相对可控
  • 可能丢失最近一次快照之后的数据

2. RDB 的触发方式

RDB 可以通过以下方式生成:

  • 满足 save 配置规则时自动触发
  • 执行 BGSAVE 手动触发后台保存
  • 执行 SAVE 手动触发前台保存(不推荐在线上使用)

常见配置示例:

save 900 1
save 300 10
save 60 10000

rdbcompression yes
rdbchecksum yes
dir /data/redis
 dbfilename dump.rdb

上面三行 save 的含义分别是:

  • 900 秒内至少有 1 次写操作,就触发一次快照
  • 300 秒内至少有 10 次写操作,就触发一次快照
  • 60 秒内至少有 10000 次写操作,就触发一次快照

3. RDB 的工作过程

在线上环境中,Redis 通常使用 BGSAVE 来生成快照。流程大致如下:

  1. Redis 主进程 fork 出子进程
  2. 子进程把当前内存数据写入临时 RDB 文件
  3. 写完后用新文件替换旧的 RDB 文件

由于采用了 fork,所以会带来两个值得注意的问题:

  • fork 本身会有一定阻塞,尤其是在大内存实例中更明显
  • 快照期间如果数据发生修改,会触发写时复制(Copy-On-Write),可能导致额外内存消耗

4. 常用命令示例

127.0.0.1:6379> BGSAVE
Background saving started

127.0.0.1:6379> LASTSAVE
(integer) 1717920000

127.0.0.1:6379> INFO persistence

其中:

  • BGSAVE:后台生成 RDB 文件
  • LASTSAVE:查看最近一次成功执行 RDB 的时间
  • INFO persistence:查看当前持久化状态

三、AOF:追加日志式持久化

1. AOF 的核心概念

AOF 的思路和 RDB 不一样。它不是记录“某一时刻的数据结果”,而是记录“数据是怎么变成现在这样的”。

比如执行了下面这些命令:

SET user:1 "Alice"
INCR counter
LPUSH tasks "job-1"

如果开启 AOF,Redis 会把这些写命令按协议格式追加到 AOF 文件中。下次重启时,Redis 只要把这些命令重新执行一遍,就能恢复出原来的数据。

AOF 的特点:

  • 数据更完整,通常比 RDB 丢失更少
  • 文件可读性更强,便于理解和排查
  • 恢复速度一般慢于 RDB
  • 长期运行后文件可能膨胀,需要重写

2. AOF 的关键配置

appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

这些配置中最关键的是 appendfsync

  • always:每次写命令都刷盘,最安全,性能开销也最大
  • everysec:每秒刷盘一次,性能和安全性比较均衡,最常用
  • no:由操作系统决定何时刷盘,性能较高,但风险更大

在大多数业务场景中,appendfsync everysec 是更常见的选择

3. AOF 重写是什么

AOF 会不断追加写命令,文件会越来越大。为了避免文件膨胀,Redis 提供了 AOF 重写

AOF 重写并不是简单地把旧文件压缩一下,而是根据当前内存中的数据,生成一份“等价但更精简”的新 AOF 文件。

例如原来文件中有很多这样的命令:

INCR counter
INCR counter
INCR counter

重写后可能变成:

SET counter 3

Redis 7.x 中,AOF 采用了 multi-part AOF 的组织方式,重写时的管理比早期版本更完善,但理解层面仍然可以抓住一句话:

AOF 重写的目标是“减少恢复成本,控制日志体积”。

常用命令:

127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started

四、RDB 与 AOF 的区别

对比项 RDB AOF
数据形式 某一时刻的数据快照 追加写命令日志
数据安全性 可能丢失最近一次快照后的数据 通常丢失更少,取决于刷盘策略
文件体积 通常更小 通常更大
恢复速度 一般更快 一般更慢
可读性 二进制,不便直接阅读 相对更容易理解
适用场景 备份、快速恢复、灾难恢复 更关注数据完整性的场景

一个很实用的理解方式是:

  • RDB 更像备份快照
  • AOF 更像操作日志

五、如何选择:只开 RDB、只开 AOF,还是都开?

1. 只开 RDB

适合场景:

  • Redis 主要作为缓存使用
  • 可以接受少量数据丢失
  • 更关注恢复速度和系统简单性

优点:

  • 配置简单
  • 文件更小
  • 恢复更快

不足:

  • 数据丢失窗口相对较大

2. 只开 AOF

适合场景:

  • 对数据完整性要求更高
  • 希望尽量减少宕机后的数据损失

优点:

  • 持久化粒度更细
  • 数据恢复更接近宕机前状态

不足:

  • 文件更大
  • 恢复时间可能更长

3. 同时开启 RDB 和 AOF

这是很多生产环境常见的方式。

因为:

  • AOF 用于提升数据安全性
  • RDB 用于加快恢复、便于备份

Redis 在加载数据时,如果同时存在 AOF 和 RDB,通常优先使用 AOF,因为 AOF 一般包含更完整的数据。


六、配置与命令示例

1. 兼顾性能与可靠性的常见配置

save 900 1
save 300 10
save 60 10000

appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 128mb

rdbcompression yes
rdbchecksum yes
stop-writes-on-bgsave-error yes

2. 排查持久化状态常用命令

INFO persistence
CONFIG GET appendonly
CONFIG GET appendfsync
CONFIG GET save
BGREWRITEAOF
BGSAVE

3. 查看持久化文件目录

CONFIG GET dir
CONFIG GET dbfilename
CONFIG GET appendfilename

七、常见问题

1. 开启 AOF 后是不是就完全不会丢数据?

不是。

如果配置为 appendfsync everysec,那么理论上仍然可能丢失 1 秒左右的数据;如果是 no,丢失窗口还可能更大。只有 always 才是每次写都刷盘,但性能代价明显。

2. 为什么大实例执行 BGSAVE 会卡顿?

主要原因有两个:

  • fork 子进程时会有阻塞
  • 快照期间写入较多时,Copy-On-Write 会造成额外内存压力

因此大内存实例需要特别关注 RDB 触发时机。

3. AOF 文件会不会无限增大?

如果不开启重写机制,确实会持续增大。实际部署中应该配置:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

让 Redis 自动在合适时机触发重写。

4. 为什么 Redis 重启恢复很慢?

常见原因包括:

  • 数据量太大
  • AOF 文件过大
  • 实例键值结构过于复杂
  • 磁盘性能不足

如果恢复速度是重点,要重点评估 RDB 的使用和 AOF 重写策略。


八、实践建议

1. 缓存型业务优先考虑简单稳定

如果 Redis 只是缓存层,后端数据库中还有完整数据,通常可以:

  • 只启用 RDB
  • 或者适当降低持久化频率

核心目标是减少性能损耗,提升可恢复性。

2. 有状态业务建议开启 AOF

如果 Redis 中存放的是:

  • 计数器
  • 排行榜
  • 延迟队列状态
  • 会话信息
  • 业务关键缓存

那么建议开启 AOF,并使用:

appendfsync everysec

在性能和可靠性之间取得平衡。

3. 预留足够内存,避免 fork 期间风险

RDB 和 AOF 重写都会涉及 fork。内存非常紧张时,持久化可能失败,甚至影响实例稳定性。实践中应为操作系统和 Copy-On-Write 预留足够内存余量。

4. 不要把持久化等同于备份

持久化解决的是“实例重启后如何恢复”的问题,但它不等于异地备份、历史归档或灾难恢复方案。重要数据仍然要有额外备份策略。

5. 定期检查持久化状态

建议把以下信息纳入巡检:

  • 最近一次 RDB 是否成功
  • AOF 是否开启
  • AOF 重写是否频繁失败
  • 持久化目录磁盘空间是否充足
  • 恢复演练是否正常

九、小结

理解 Redis 持久化,关键是抓住下面三点:

  1. RDB 是快照,恢复快,但可能丢失更多近期数据
  2. AOF 是日志,数据更完整,但文件更大、恢复可能更慢
  3. 生产中常常会组合使用 RDB 与 AOF,兼顾恢复速度与数据安全性

如果你在学习 Redis 的核心特性,RDB 与 AOF 是必须掌握的基础。后续再看主从复制、哨兵、集群时,你会发现持久化能力与高可用设计是互相关联的。


📝 版权声明:本文为原创技术博客,转载请注明出处。

如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!

上一篇

Redis入门1.4: 常用命令速查与 CLI 技巧

下一篇

Redis核心2.2: 过期键与内存淘汰机制