Redis 持久化:断电了数据怎么不丢?RDB 和 AOF 怎么选
作者:鱼宵 | 实战驱动系列 · 第 9 篇
完整课程与可运行源码已开源在 Gitee:gitee.com/j67mk2/redi… (本文对应 lesson-03/)
一、问题:内存数据库,宕机了数据不就全没了?
Redis 快,是因为数据都放内存里。但内存有个致命缺点:断电/进程退出就清空。如果里面存的是库存、登录会话,一重启全没了,业务直接崩。
所以 Redis 提供了两种"存盘"手段:RDB 和 AOF。这篇把它们拆透,并亲手触发一次快照看到文件生成。
二、RDB:拍快照(拍照片)
类比:给当前整个柜子"拍一张照片"。咔嚓一下,把此刻所有东西的样子存成 dump.rdb 文件。
- 什么时候拍:
- 按配置自动拍——Redis 7 默认规则
save 3600 1 300 100 60 10000,意思是:1 小时内至少 1 个 key 变了拍一次;5 分钟内至少 100 个 key 变了拍一次;60 秒内至少 1 万个 key 变了拍一次。(老教程常见的save 900 1意思一样:900 秒内 1 个 key 变了就拍。) - 手动拍——
save(阻塞式,卡住主进程,生产别用)或bgsave(后台 fork 子进程去拍,推荐)。 - 正常关闭时
shutdown自动存一次。
- 按配置自动拍——Redis 7 默认规则
- 优缺点:👍 文件小、恢复飞快(直接把文件灌回内存)。👈 两次快照之间新写的数据会丢——1 小时拍一次,拍完后第 59 分钟宕机,这 59 分钟数据全没了,丢数据窗口大。
亲手触发一次(实测):
$ docker exec redis-l3 redis-cli BGSAVE
Background saving started
$ docker exec redis-l3 ls -lh /data
-rw------- 1 redis redis 161 Oct 2 07:50 dump.rdb <- 快照文件出现了
$ docker exec redis-l3 redis-cli INFO persistence
rdb_last_bgsave_status:ok <- 快照成功
三、AOF:记账本(append-only file)
类比:RDB 是拍照片,AOF 是记账本。不拍整张照片,而是把"每一条写命令"都像记账一样追加记到 appendonly.aof。重启时把本子上的命令从头到尾再执行一遍,数据就回来了。
- 怎么做:
SET a 1、INCR counter这些写命令都会被记下来,读命令(GET)不记。 - 多久写一次(appendfsync 三档):
| 配置 | 人话 | 安全 vs 性能 |
|---|---|---|
always | 每写一条就立刻刷盘 | 最安全,但最慢 |
everysec | 每秒刷一次盘(默认) | 折中:最多丢 1 秒 |
no | 交给操作系统 | 最快,丢多少不可控 |
- AOF 重写(bgrewriteaof):记账本会越来越厚。你对同一个 key
set age 1 → set age 2 → set age 3,本子上记了 3 条,其实最后只要set age 3一条就够了。类比:账本太厚了重新誊一遍,把啰嗦的旧命令压缩成"最少能还原当前状态"的几条,文件就瘦了。
亲手开启 AOF(实测):
$ docker exec redis-l3 redis-cli CONFIG SET appendonly yes
OK
$ docker exec redis-l3 ls -lh /data/appendonlydir
-rw------- 1 redis redis 217 Oct 2 07:51 appendonly.aof.1.base.rdb
-rw------- 1 redis redis 0 Oct 2 07:51 appendonly.aof.1.incr.aof
-rw------- 1 redis redis 88 Oct 2 07:51 appendonly.aof.manifest
注意那个文件名:appendonly.aof.1.base.rdb——后缀是 .rdb!这就是 Redis 7 混合持久化的铁证:AOF 的基础部分用 RDB 格式存,增量命令记在 incr.aof,manifest 是清单。老教程说"看 appendonly.aof",在 Redis 7 里找不到——去 appendonlydir 目录看。
四、混合持久化:既要又要
RDB 恢复快、AOF 数据安全,能不能都占?Redis 4.0 引入 aof-use-rdb-preamble(混合持久化):AOF 重写时,前半段用 RDB 格式存全量快照,后半段记增量命令。既享受 RDB 恢复快,又保留 AOF 少丢数据。Redis 7 默认就是这么干的。
五、一张表总结(面试直接背)
| RDB(拍快照) | AOF(记账本) | |
|---|---|---|
| 存的是什么 | 某一时刻全量数据的二进制快照 | 一条条写命令 |
| 文件 | dump.rdb | appendonly.aof.*(Redis 7 拆 base+incr+manifest) |
| 丢数据 | 多(两次快照之间) | 少(everysec 最多丢 1 秒) |
| 恢复速度 | 快 | 慢(要重放命令) |
| 文件体积 | 小 | 大 |
| 适合 | 备份、容灾、能容忍丢一点 | 对数据安全要求高 |
能不能都开? 能,生产推荐都开:RDB 做冷备份/快速恢复,AOF 保证少丢数据。
六、挑战题
- ⭐ 亲手触发一次
BGSAVE,用ls -lh /data看到dump.rdb从无到有。 - ⭐⭐ 故意
CONFIG SET appendonly no关掉 AOF,docker restart后数据还在吗?反过来只开 RDB,宕机后两次快照之间新写的数据还在不在?动手验证"丢数据窗口"。 - ⭐⭐⭐ 给一个"不能丢订单数据"的生产 Redis 选持久化方案:写出你的
save规则、appendonly、appendfsync选择,并说明理由。
七、面试回答模板
面试官:RDB 和 AOF 区别?
RDB 是拍快照,存某一时刻全量数据的二进制文件,文件小、恢复快、但丢数据窗口大;AOF 是记账本,记每一条写命令,更安全(everysec 最多丢 1 秒)但文件大、恢复慢。
追问:能不能都开?
能,生产推荐都开,RDB 做冷备份、AOF 保证少丢;Redis 4.0+ 混合持久化把两者结合——AOF 重写时前半段 RDB 后半段 AOF。
追问:AOF 重写原理?
fork 子进程把当前数据重新算成最小命令集写新文件,期间新命令记在缓冲区最后追加;写时复制(COW)让父进程继续接业务,不会卡住。
关于这个系列
本文是「Java 后端实战精通营」系列第 9 篇,原则:实战驱动、由浅到深、面试向。
👉 Redis 实战精通营(10 课):gitee.com/j67mk2/redi…
- 本文对应源码位置:
lesson-03/(Java 触发 BGSAVE + 查持久化配置的 demo)
下一篇预告:《Redis 过期策略与内存淘汰:缓存穿透/击穿/雪崩一次讲透》——数据放多久该删、内存满了踢谁、面试必考的缓存三兄弟。
跑完有任何报错,把终端输出发评论区,一起排查。