为什么需要持久化?
Redis 虽然快,但它的数据主要存储在内存中,而内存属于易失性存储介质。
一旦断电或者服务重启,如果没有持久化机制,数据就可能丢失。
所以 Redis 提供了两种持久化方案:RDB 和 AOF,前者是数据快照,后者是命令日志。
面试的时候面试官常问这个问题,很多人只答出"两种方案"就结束了,其实还需要深入讲清楚原理和取舍。
RDB:数据快照
什么是 RDB?
RDB(Redis Database Backup)就是把某一时刻的内存数据完整写入磁盘,生成一个二进制文件。下次启动时,Redis 读取这个文件,把数据恢复到内存里。
说人话就是:
给内存拍一张照片,事后按照片还原。
手动触发
可以用两条命令手动生成 RDB 文件:
SAVE:由主进程执行,会阻塞所有其他操作。文件大时风险很高,生产环境基本不用。BGSAVE:由子进程执行,异步操作,对主进程影响极小。生产环境用这个。
自动触发
Redis 配置文件里有三行默认规则,Redis 会周期性检查 save 配置,当任意条件满足时,会触发后台执行 BGSAVE。
plain
save 900 1 # 900 秒内至少有 1 个 key 被修改
save 300 10 # 300 秒内至少有 10 个 key 被修改
save 60 10000 # 60 秒内至少有 10000 个 key 被修改
你可以根据业务情况修改这些阈值。

RDB 的执行原理
很多人知道 BGSAVE 用子进程,但不知道为什么不会阻塞主进程。
这就要从内存模型说起。
Linux 系统中,进程不能直接操作物理内存,而是通过虚拟内存 + 页表来间接访问。
页表记录了虚拟地址和物理地址的映射关系。
执行 BGSAVE 时,Redis 会 fork 出一个子进程。
关键点在于:fork 只复制页表,不复制数据。
子进程拿到与主进程相同的映射关系后,就能读取相同的物理内存数据,而无需拷贝任何实际内容。 fork 本身不会复制大量数据,只需要复制页表,因此相比完整复制内存开销非常小。

Copy on Write 解决了什么?
子进程在写 RDB 文件的同时,主进程也在接收用户的写请求。
如果两者直接共享内存,就会出现读写冲突,产生脏数据。
解决办法是 Copy on Write(写时复制):
fork 之后,共享内存被标记为只读。
当主进程收到写请求时,操作系统会把被修改的内存页单独拷贝一份,主进程写新副本,子进程继续读旧副本。
这样就避免了数据竞争。
说人话就是:
有人要改,我就抄一份给你改,原文件不动。

AOF:命令日志
什么是 AOF?
AOF(Append Only File)记录的是 Redis 执行的每一个写命令。
每次执行写操作,命令就会被追加到 AOF 文件末尾。
说人话就是:
把所有写操作写成日记,重启时重放日记就能恢复数据。
比如你执行了三条命令:
plain
SET number 123
SET name jack
SET number 666
AOF 会按照 Redis 协议格式记录每一次写命令,而不是简单保存命令字符串。
开启与刷盘策略
AOF 默认是关闭的,需要在配置文件中将 appendonly 改为 yes。
AOF 有三种刷盘频率:
| 策略 | 说明 | 可靠性 | 性能 |
|---|---|---|---|
always |
每次写命令都立即刷盘 | 最高,几乎不丢数据 | 最差 |
everysec |
每秒执行一次 fsync | 较高, 通常最多丢失约 1 秒数据 | 适中 |
no |
由操作系统决定何时刷盘 | 最低,可能丢大量数据 | 最好 |
生产环境推荐使用everysec,兼顾安全性和性能。
AOF 重写
AOF 有个明显缺点:文件体积大。
同一个 key 写 100 次,AOF 就记 100 行,但实际只有最后一次有效。
Redis 提供了 BGREWRITEAOF 命令来重写 AOF 文件,用最少命令还原相同的数据状态。
比如上面的例子, 重写后只保留最终状态对应的写命令,例如:
plain
SET name jack
SET number 666
只保留最终结果,大幅压缩文件体积。
可以通过两个条件自动触发重写:
- 体积增长比例:当前 AOF 文件比上一次重写后的文件增长超过设定百分比(默认 100%)就触发。
- 绝对体积阈值:AOF 文件超过设定大小(默认 64MB)就触发。

RDB vs AOF:怎么选?
| 维度 | RDB | AOF |
|---|---|---|
| 持久化方式 | 整份内存快照 | 逐条记录写命令 |
| 数据完整性 | 两次备份之间可能丢数据 | 通常最多丢失约 1 秒数据 |
| 文件大小 | 小(二进制压缩) | 大(文本命令日志) |
| 恢复速度 | 快 | 慢(文件大) |
| 默认恢复顺序 | 较低 | 较高(开启 AOF 时优先加载) |
| 资源占用 | fork 时占用较多 CPU 和内存 | 主要占用磁盘 I/O |
| 适用场景 | 可容忍数分钟数据丢失 | 对数据安全性要求高 |
面试加分回答
如果面试官问"你们项目用哪个",推荐回答:
Redis 4.0 引入混合持久化(AOF rewrite 时结合 RDB 格式),进一步提升恢复速度。
AOF 保证日常数据安全性,RDB 作为后备,在 AOF 文件损坏时提供快速恢复能力。两者结合,既保数据安全,又保恢复效率。
这样回答既体现了理解深度,又展示了实际工程经验。