1. Redis 为什么需要持久化
Redis 主要在内存中读写数据。如果只把它当纯缓存,进程重启后缓存丢失通常可以接受;但如果 Redis 中保存了排行榜、计数器、会话、消息流、库存扣减中间状态等数据,就要考虑重启后的恢复问题。
Redis 持久化主要有两种方式:
| 方式 | 核心思路 | 适合场景 |
|---|---|---|
| RDB | 按时间点生成内存快照 | 备份、全量恢复、对数据实时性要求不高 |
| AOF | 记录每次写命令,重启时重放 | 对数据丢失更敏感,希望恢复到更近时间点 |
可以先明确一个判断原则:如果 Redis 中只是缓存,持久化可以关闭;如果 Redis 中有业务状态,至少要开启 AOF everysec,并结合磁盘性能、fsync 策略和业务容忍度评估数据丢失窗口。
2. RDB 是什么
RDB,全称 Redis Database,是 Redis 在某个时间点生成的内存快照文件。
可以把 RDB 理解成“拍照”:Redis 在某个时刻把内存里的数据集保存成一个二进制文件,默认文件名通常是 dump.rdb。真正落地时,BGSAVE 的核心机制是 fork 子进程,并依赖操作系统的 copy-on-write 让子进程看到生成快照时的数据视图。

2.1 RDB 的特点
| 特点 | 说明 |
|---|---|
| 文件紧凑 | RDB 是压缩后的二进制快照,适合备份和传输 |
| 恢复速度快 | 恢复时直接加载快照,比逐条命令重放更快 |
| 有时间窗口 | 两次快照之间如果 Redis 宕机,中间写入会丢失 |
| fork 子进程 | BGSAVE 会 fork 子进程做持久化,主进程继续服务 |
| 可能有额外内存压力 | fork 后写时复制可能带来内存放大 |
3. RDB 如何触发
RDB 有自动触发和手动触发两类。
3.1 自动触发
配置文件中通过 save 规则控制:
save 3600 1
save 300 100
save 60 10000
含义是:
| 配置 | 说明 |
|---|---|
| save 3600 1 | 3600 秒内至少 1 次修改则触发 |
| save 300 100 | 300 秒内至少 100 次修改则触发 |
| save 60 10000 | 60 秒内至少 10000 次修改则触发 |
注意:不同 Redis 版本默认 save 配置可能不同,实际以本机 redis.conf 为准。
多条 save 规则之间是 OR 关系,只要任意一条规则满足,就会触发一次后台快照。
3.2 手动触发
手动触发有两个命令:
save
bgsave
区别如下:
| 命令 | 说明 | 是否阻塞 |
|---|---|---|
| SAVE | 主进程直接执行 RDB 保存 | 会完全阻塞 Redis 主线程 |
| BGSAVE | fork 子进程执行 RDB 保存 | 主进程不长时间阻塞,但 fork 有瞬时开销 |
# 生产环境一般不要直接执行 SAVE,更常用 BGSAVE
127.0.0.1:6379> SAVE # 手动执行 RDB 持久化,会阻塞 Redis 主线程,生产环境慎用
OK
127.0.0.1:6379> BGSAVE # 后台异步执行 RDB 持久化,生产环境更常用
Background saving started
127.0.0.1:6379> LASTSAVE # 查看最近一次 RDB 保存成功的 Unix 时间戳
(integer) 1727500200
# RDB 自动保存规则
# 表示 3600 秒内至少有 1 个 key 发生变化,就触发一次 RDB 保存
# 表示 300 秒内至少有 100 个 key 发生变化,就触发一次 RDB 保存
# 表示 60 秒内至少有 10000 个 key 发生变化,就触发一次 RDB 保存
save 3600 1 300 100 60 10000
# 自定义保存规则
# 表示 5 秒内至少有 2 个 key 发生变化,就触发一次 RDB 保存
save 5 2
# 注意:这里必须指定目录,而不是文件名
# RDB 文件保存目录
dir ./myredis/dumpfiles
# RDB 文件名
dbfilename dump6379.rdb
SAVE 会让 Redis 主线程直接做快照保存。在 Redis 单线程执行命令的模型下,这意味着保存期间其它客户端请求都无法被正常处理,所以生产环境通常不直接使用。
BGSAVE 的主要保存工作由子进程完成,但不能理解为完全没有影响。fork 本身会短暂阻塞主线程;如果实例内存很大,fork 延迟会变明显。fork 之后如果主进程持续写入大量数据,copy-on-write 会带来额外内存占用。
4. RDB 相关配置
常用配置项如下:
dir /myredis
dbfilename dump6379.rdb
rdbcompression yes
rdbchecksum yes
stop-writes-on-bgsave-error yes
save 3600 1 300 100 60 10000
参数说明:
| 参数 | 说明 |
|---|---|
| dir | RDB 文件所在目录 |
| dbfilename | RDB 文件名 |
| rdbcompression | 是否压缩 RDB 文件 |
| rdbchecksum | 是否开启校验 |
| stop-writes-on-bgsave-error | 后台保存失败后是否停止写入,用来避免“写入成功但无法持久化”的风险 |
| save | 自动快照触发规则 |
如果想关闭自动 RDB 快照:
save ""
也可以在线修改:
config set save ""
但在线修改只是当前实例生效,是否持久保存取决于后续是否执行 CONFIG REWRITE 以及配置文件权限,生产上更推荐直接改配置并走发布流程。
5. RDB 文件检查和恢复
检查 RDB 文件:
redis-check-rdb /myredis/dump6379.rdb
下面检查命令如下:
[root@hadoop100 ~]# cd /usr/local/bin/
[root@hadoop100 bin]# ll
总用量 21552
-rwxr-xr-x. 1 root root 5205192 9月 28 13:10 redis-benchmark
lrwxrwxrwx. 1 root root 12 9月 28 13:10 redis-check-aof -> redis-server
lrwxrwxrwx. 1 root root 12 9月 28 13:10 redis-check-rdb -> redis-server
-rwxr-xr-x. 1 root root 5422600 9月 28 13:10 redis-cli
lrwxrwxrwx. 1 root root 12 9月 28 13:10 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 11436976 9月 28 13:10 redis-server
[root@hadoop100 bin]# redis-check-rdb /myredis/dumpfiles/dump6379.rdb
[offset 0] Checking RDB file /myredis/dumpfiles/dump6379.rdb
[offset 27] AUX FIELD redis-ver = '7.0.11'
[offset 41] AUX FIELD redis-bits = '64'
[offset 53] AUX FIELD ctime = '1727500200'
[offset 68] AUX FIELD used-mem = '1029512'
[offset 80] AUX FIELD aof-base = '0'
[offset 89] Checksum OK
[offset 89] \o/ RDB looks OK! \o/
[info] 0 keys read
[info] 0 expires
[info] 0 already expired
[root@hadoop100 bin]#
恢复 RDB 的基本过程:
- 停止 Redis
- 将 RDB 文件放到 dir 指定目录
- 文件名改成 dbfilename 配置的名字
- 启动 Redis
- 使用 dbsize、业务 key、抽样查询验证恢复结果
示例:
redis-cli -p 6379 --pass 111111 shutdown
cp dump6379.rdb /myredis/dump6379.rdb
redis-server /myredis/redis7.conf
redis-cli -p 6379 --pass 111111 dbsize
实际恢复时,Redis 启动会自动在 dir 指定目录查找 dbfilename 对应的 RDB 文件并加载,不需要额外执行“恢复命令”。手动步骤的重点是把文件放到正确目录、使用正确文件名,并在启动后验证 key 数量和业务数据。
6. RDB 的优缺点
6.1 优点
- 文件紧凑,适合做周期性备份。
- 恢复速度快,适合大规模数据全量恢复。
- 对主进程影响相对较小,BGSAVE 由子进程完成主要工作。
6.2 缺点
- 两次快照之间的数据可能丢失。
- fork 时可能带来内存压力,copy-on-write 在高写入场景下可能让内存占用明显放大,极端情况下接近额外一份数据集。
- 快照很大时,磁盘 IO 会明显上升,也可能带来延迟抖动。
所以 RDB 更适合“允许丢一段时间窗口数据,但希望恢复快”的场景。
7. AOF 是什么
AOF,全称 Append Only File。它不是保存某个时刻的数据快照,而是把 Redis 执行过的写命令追加到日志文件中。Redis 重启时重新执行这些命令,从而恢复数据。
对比 RDB:
| 对比项 | RDB | AOF |
|---|---|---|
| 记录内容 | 数据快照 | 写命令日志 |
| 恢复方式 | 加载快照 | 重放命令 |
| 文件大小 | 通常较小 | 通常较大,需要重写 |
| 数据丢失窗口 | 取决于快照间隔 | 取决于 fsync 策略 |
| 恢复速度 | 通常更快 | 命令多时更慢 |
7.1 AOF 持久化工作流程
AOF 的全称是 Append Only File,它会把 Redis 执行过的写命令追加保存到 AOF 文件中。Redis 重启时,可以通过重新执行 AOF 文件中的命令来恢复数据。
AOF 持久化的大致流程如下:

| 步骤 | 说明 |
|---|---|
| 1 | Client 作为命令的来源,会不断向 Redis Server 发送写命令。 |
| 2 | 写命令到达 Redis Server 后,并不是直接写入 AOF 文件,而是先写入 AOF 缓冲区。AOF 缓冲区是内存中的一片区域,用来临时保存写命令,避免每条命令都立即进行磁盘 IO。 |
| 3 | Redis 会根据 AOF 缓冲区同步文件的写回策略,将缓冲区中的命令写入磁盘上的 AOF 文件。 |
| 4 | 随着 AOF 内容不断增加,AOF 文件会越来越大。为了避免文件膨胀,Redis 会根据规则进行命令合并,也就是 AOF 重写,从而达到压缩 AOF 文件的目的。 |
| 5 | 当 Redis Server 重启时,会从 AOF 文件 中重新加载数据,恢复 Redis 中的数据状态。 |
这里有两层缓冲要区分:第一层是 Redis 自己维护的 AOF buffer,第二层是操作系统的 page cache。Redis 把数据写给内核之后,并不等于数据已经落到物理磁盘,真正落盘还取决于 fsync 策略和操作系统调度。
简单来说,AOF 的流程可以理解为:
Client 写命令
↓
Redis Server 接收命令
↓
写入 AOF 缓冲区
↓
根据写回策略刷入 AOF 文件
↓
AOF 文件过大时触发 AOF 重写
↓
Redis 重启时加载 AOF 文件恢复数据
8. 开启 AOF
核心配置:
appendonly yes
appendfilename "appendonly.aof"
appenddirname "appendonlydir"
appendfsync everysec
Redis 7 需要特别注意:AOF 默认采用 multi-part AOF 机制,不一定只看到一个单独的 appendonly.aof 文件。通常会在 appenddirname 指定目录下看到 manifest、base、incr 等文件。其中 manifest 是核心索引文件,用来记录当前有效的 base 文件和 incr 文件。
可以在数据目录下查看:
ls -lh /myredis/appendonlydir
如果使用 Redis 7,看到类似下面的文件是正常的:
appendonly.aof.manifest
appendonly.aof.1.base.rdb
appendonly.aof.1.incr.aof
其中 base.rdb 是重写时生成的全量基线文件,incr.aof 是基线之后继续追加的增量写命令。Redis 启动恢复时会根据 manifest 组合加载这些文件。这点和很多旧文章只讲单个 AOF 文件不同。
9. AOF 三种写回策略
AOF 写命令进入缓冲区后,需要通过 fsync 刷到磁盘。appendfsync 有三种策略:
| 策略 | 配置 | 说明 |
|---|---|---|
| 每条命令刷盘 | appendfsync always | 最安全,但性能损耗最大 |
| 每秒刷盘 | appendfsync everysec | 性能和可靠性折中,通常最多丢 1 秒级数据 |
| 交给系统决定 | appendfsync no | 性能好,但丢失窗口不可控 |
生产上最常见的是:
appendfsync everysec
这是 Redis 官方实践中很常见的折中选择。它不保证绝对零丢失,但性能和可靠性比较平衡。
需要注意,everysec 的“1 秒”是通常情况下的经验窗口,不是严格承诺。Linux 磁盘 flush、虚拟化存储、IO 拥塞或系统极端抖动,都可能让实际落盘延迟变大。生产环境要结合磁盘性能、监控指标和业务可接受丢失窗口评估,而不是只记“最多丢 1 秒”。
10. AOF 文件检查和修复
检查 AOF 前先看当前是不是 Redis 7 的 multi-part AOF。如果 appendonlydir 下存在 manifest 文件,先根据 manifest 和启动日志确认具体的 base、incr 文件,再检查对应文件;如果是旧版本或单文件 AOF,再检查具体的 AOF 文件。
# Redis 7 multi-part AOF,按实际文件名检查 incr 或 base 文件
redis-check-aof /myredis/appendonlydir/appendonly.aof.1.incr.aof
# 旧版或单文件 AOF
redis-check-aof /myredis/appendonly.aof
如果 AOF 尾部损坏,可以尝试修复。修复前必须先备份目录或文件:
cp -r /myredis/appendonlydir /myredis/appendonlydir.bak
然后按实际文件形态执行修复:
# Redis 7 multi-part AOF,按日志提示修复具体损坏的 AOF 文件
redis-check-aof --fix /myredis/appendonlydir/appendonly.aof.1.incr.aof
# 旧版或单文件 AOF
redis-check-aof --fix /myredis/appendonly.aof
如果 Redis 启动日志明确提示某个 AOF 文件损坏,则以日志中的文件路径为准。不要在没有备份的情况下直接执行 –fix。
常见 AOF 配置如下:
# 开启 AOF 持久化
# yes 表示开启,Redis 会把执行过的写命令追加保存到 AOF 文件中
appendonly yes
# AOF 写回策略:每次写命令都同步写入磁盘
# 数据安全性最高,但性能影响最大,生产环境一般不推荐
# appendfsync always
# AOF 写回策略:每秒写入一次磁盘
# 性能和数据安全比较均衡,生产环境常用配置
appendfsync everysec
# AOF 写回策略:由操作系统决定什么时候写入磁盘
# 性能最好,但宕机时可能丢失较多数据
# appendfsync no
11. AOF 重写机制
AOF 是追加日志,随着写入越来越多,文件会越来越大。比如对同一个 key 执行了 100 次 INCR,最终恢复数据时其实只需要最后的值,不需要完整保留中间 100 条命令。
AOF 重写就是把冗余命令压缩成恢复当前数据集所需的最小命令集合。重写由 BGREWRITEAOF fork 出的子进程完成,主线程仍然可以继续处理请求,但 fork、磁盘写入和后续文件切换都会带来额外 CPU、内存和 IO 压力。
手动触发:
bgrewriteaof
自动触发常用配置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
含义是:当 AOF 文件比上次重写后增长 100%,并且文件至少达到 64MB 时,触发重写。
# 几种类型文件的前缀,后跟有关序列和类型的附加信息
appendfilename "appendonly.aof"
# 新版本增加的目录配置项目
appenddirname "appendonlydir"
# 如果 appendonlydir 下存在 multi-part AOF,通常会看到下面几类文件:
1. 基础文件
appendonly.aof.1.base.rdb
2. 增量文件
appendonly.aof.1.incr.aof
appendonly.aof.2.incr.aof
3. 清单文件
appendonly.aof.manifest
重写后的结果通常是:
- 文件更小
- 重启恢复更快
- 冗余历史命令减少
所以 bgrewriteaof 不应理解成“完全无影响”。大实例或慢磁盘环境里,AOF rewrite 可能造成 IO 抢占和 latency spike。生产上要关注 INFO persistence、磁盘 util、fork 耗时和 Redis 延迟监控。
12. AOF 的优缺点
12.1 优点
- 数据丢失窗口更小。
- 日志追加,语义直观。
- everysec 策略在性能和可靠性之间比较平衡。
12.2 缺点
- 文件通常比 RDB 大。
- 恢复时需要重放命令,可能比 RDB 慢。
- AOF 写入、fsync 和 rewrite 会带来额外 IO,并可能造成延迟抖动。
- 如果不了解 Redis 7 multi-part AOF,排查文件时容易误判。
13. RDB 和 AOF 同时开启
Redis 可以同时开启 RDB 和 AOF。
配置示例:
save 3600 1 300 100 60 10000
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
当 RDB 和 AOF 同时存在时,Redis 重启恢复通常会优先使用 AOF,因为 AOF 往往包含更完整的数据变化。
aof-use-rdb-preamble yes 表示 AOF 重写时使用 RDB 格式作为 AOF 文件的前半部分,再追加增量 AOF 内容。这就是 RDB + AOF 的混合格式。它的核心收益是提升恢复速度:启动时先快速加载 RDB 基线,再重放较短的增量 AOF。
| 配置指令 | 配置含义 | 配置示例 |
|---|---|---|
| appendonly | 是否开启 AOF | appendonly yes |
| appendfilename | AOF 文件名称 | appendfilename “appendonly.aof” |
| appendfsync | AOF 同步方式 | everysec / always / no |
| no-appendfsync-on-rewrite | AOF 重写期间是否同步 | no-appendfsync-on-rewrite no |
| auto-aof-rewrite-percentage | AOF 自动重写触发比例 | auto-aof-rewrite-percentage 100 |
| auto-aof-rewrite-min-size | AOF 自动重写触发的最小文件大小 | auto-aof-rewrite-min-size 64mb |
14. 如何选择持久化方案
可以按下面这张表判断。
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 纯缓存,数据可从数据库重建 | 关闭持久化或只保留 RDB | 重启后重新预热即可 |
| 普通业务缓存,希望重启恢复快 | RDB | 文件小,恢复快 |
| 计数、排行、状态等不希望丢太多 | AOF everysec | 通常是秒级丢失窗口,但要结合磁盘和 fsync 状态评估 |
| 希望兼顾恢复速度和较小丢失窗口 | AOF + 混合持久化 | 重写后前半段是 RDB,后半段是增量 AOF |
| 极端要求零丢失 | Redis 不应作为唯一存储 | 即使 always 也要考虑系统、磁盘、复制链路和业务事务 |
我个人更常用的组合是:
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
save 3600 1 300 100 60 10000
但最终要看业务是否允许丢失、磁盘性能和恢复时间要求。纯 cache、业务 state、轻量 queue 的持久化策略不应该完全相同:缓存更看重恢复速度和预热能力,状态数据更看重丢失窗口,队列类数据还要评估 ACK、重复消费和业务补偿。
本质上,持久化选择是在恢复速度、数据完整性、CPU/fork 成本和磁盘 IO 之间做权衡。RDB 更偏 CPU/fork 和快照备份,AOF 更偏持续 IO 和更小丢失窗口,混合持久化则试图在恢复速度和完整性之间取中间值。
15. 纯缓存模式
如果 Redis 明确只做缓存,不需要落盘,可以关闭 RDB 和 AOF:
save ""
appendonly no
这种方式重启最快,也避免了持久化 IO,但代价是 Redis 重启后数据全部丢失。
16. 排查持久化问题的常用命令
实际排查时常用这些命令:
# 查看持久化相关信息
info persistence
# 查看配置
config get save
config get appendonly
config get appendfsync
config get dir
config get dbfilename
config get appendfilename
config get appenddirname
# 手动触发
bgsave
bgrewriteaof
# 检查文件
redis-check-rdb /myredis/dump6379.rdb
redis-check-aof /myredis/appendonlydir/appendonly.aof.1.incr.aof
INFO persistence 里重点看:
| 字段 | 说明 |
|---|---|
| rdb_last_bgsave_status | 最近一次 RDB 是否成功 |
| rdb_last_save_time | 最近一次 RDB 保存时间 |
| aof_enabled | AOF 是否开启 |
| aof_last_bgrewrite_status | 最近一次 AOF 重写是否成功 |
| aof_current_size | 当前 AOF 大小 |
| aof_base_size | 上次重写后的 AOF 基准大小 |
17. 本文小结
Redis 持久化不要只记“RDB 快、AOF 安全”这种口号,要看数据丢失窗口、恢复速度、fork/COW 内存压力、磁盘 IO 和运维复杂度。
核心结论如下:
- RDB 是快照,适合备份和快速恢复,但可能丢失两次快照之间的数据。
- AOF 是写命令日志,everysec 是常见折中,通常是秒级丢失窗口,但极端 IO 抖动下可能更大。
- Redis 7 的 AOF 可能是 multi-part AOF,要根据 manifest 找 base 和 incr 文件,不要只找一个单独的 appendonly.aof。
- 混合持久化通过 aof-use-rdb-preamble yes 使用 RDB 基线加增量 AOF,核心收益是提高恢复速度。
- 如果 Redis 只是缓存,可以关闭持久化;如果 Redis 保存业务状态,必须明确最多能接受丢多少数据。
下一篇继续看 Redis 单机能力:事务、Pipeline 和发布订阅。