Redis 作为最流行的内存数据库之一,以其极高的读写性能著称。但内存数据在断电或进程崩溃后会全部丢失,因此持久化机制是 Redis 高可用体系中不可或缺的一环。Redis 提供了两种主要的持久化方式:RDB(Redis DataBase)和 AOF(Append Only File)。理解它们的区别,不仅是面试中的高频考点,更是生产环境选型与调优的基础。
一、RDB:快照式持久化
RDB 的核心思想是在指定时间间隔内,将内存中的数据集快照写入磁盘,生成一个经过压缩的二进制文件(默认名为 dump.rdb)。
1. 触发方式
RDB 的触发分为手动和自动两类:
- 手动触发:
SAVE命令会阻塞 Redis 主线程直到快照完成,生产环境应避免使用;BGSAVE命令则 fork 出一个子进程在后台完成快照,主进程继续处理请求。 - 自动触发:通过配置文件中的
save指令设置,例如save 900 1表示 900 秒内至少有 1 个 key 被修改就触发 BGSAVE。此外,执行SHUTDOWN或从节点全量同步时也会触发 RDB。
2. 底层原理:fork 与写时复制
BGSAVE 依赖操作系统的 fork + COW(Copy-On-Write,写时复制) 机制。fork 出的子进程与父进程共享同一份内存页,只有当父进程修改某个内存页时,内核才会复制该页给子进程。这样既避免了全量内存拷贝的开销,又保证了快照数据的一致性。但需要注意的是,fork 本身在内存较大时会有短暂的阻塞,且写入频繁时 COW 会导致内存占用膨胀。
3. 优缺点
优点:
- 文件紧凑,是经过压缩的二进制格式,适合备份和灾难恢复。
- 恢复速度快,直接加载到内存即可,远快于 AOF 的重放。
- 对主进程性能影响小,子进程负责 I/O。
缺点:
- 数据安全性低,两次快照之间的数据可能丢失。例如每 5 分钟快照一次,宕机可能丢失近 5 分钟的数据。
- fork 子进程时若数据集很大,会造成毫秒级甚至秒级的阻塞。
二、AOF:日志式持久化
AOF 的核心思想是以追加的方式记录每一条写命令,以 Redis 协议格式保存为文本文件。重启时通过重新执行这些命令来恢复数据。
1. 写入流程
AOF 的写入分为三步:
- 命令追加:写命令执行后追加到
aof_buf缓冲区。 - 文件写入:根据
appendfsync策略将缓冲区内容写入磁盘。 - 文件同步:调用 fsync 将内核缓冲区刷到磁盘。
2. 三种同步策略
appendfsync 决定了数据安全与性能的权衡:
- always:每条命令都 fsync,数据最安全,但性能最差,QPS 会大幅下降。
- everysec:每秒 fsync 一次,是默认配置,兼顾性能与安全,最多丢失 1 秒数据。
- no:由操作系统决定何时刷盘,性能最好,但丢失数据不可控。
3. AOF 重写
随着时间推移,AOF 文件会不断膨胀。例如对同一个 key 执行 100 次 INCR,AOF 中会记录 100 条命令,而实际只需一条 SET 即可恢复。AOF 重写(Rewrite) 就是根据当前内存状态生成一份精简的新 AOF 文件。重写同样通过 fork 子进程完成,重写期间的新命令会写入 AOF 重写缓冲区,待重写完成后追加到新文件,保证数据不丢失。
4. 优缺点
优点:
- 数据安全性高,
everysec下最多丢失 1 秒数据,always下几乎不丢。 - 文件为文本格式,可读性强,便于排查问题。
- 支持追加写入,不会因写入中断而破坏已有数据。
缺点:
- 文件体积通常远大于 RDB。
- 恢复速度慢,需要逐条重放命令。
- 在高写入场景下,AOF 重写和 fsync 会带来额外的性能开销。
三、核心区别对比
| 对比维度 | RDB | AOF |
|---|---|---|
| 持久化方式 | 快照,记录某一时刻的数据 | 日志,记录每一条写命令 |
| 文件格式 | 二进制,紧凑 | 文本,Redis 协议格式 |
| 数据安全性 | 低,可能丢失数分钟数据 | 高,最多丢失 1 秒 |
| 恢复速度 | 快 | 慢 |
| 文件体积 | 小 | 大 |
| 对性能影响 | fork 时短暂阻塞 | fsync 策略影响较大 |
| 适用场景 | 备份、灾难恢复、容忍少量丢失 | 数据安全性要求高的场景 |
四、混合持久化:兼得鱼与熊掌
Redis 4.0 引入了混合持久化(通过 aof-use-rdb-preamble yes 开启)。其原理是:AOF 重写时,将当前内存数据以 RDB 格式写入新 AOF 文件的开头,后续的增量命令以 AOF 格式追加。这样重启时先加载 RDB 部分实现快速恢复,再重放少量 AOF 命令保证数据完整,兼顾了 RDB 的恢复速度和 AOF 的数据安全性。这也是 Redis 5.0 之后的默认推荐配置。
五、生产环境如何选择
- 对数据安全性要求极高(如金融、订单场景):建议开启 AOF +
everysec,同时保留 RDB 用于备份。 - 允许少量数据丢失、追求性能(如缓存场景):可仅使用 RDB。
- 通用推荐:同时开启 RDB 和 AOF,并启用混合持久化,这是目前最稳妥的方案。
六、面试高频追问
- BGSAVE 期间数据被修改了怎么办? 依赖 COW 机制,子进程读取的是 fork 时刻的内存页副本,父进程的修改不影响子进程。
- AOF 重写期间的新命令会丢吗? 不会,会写入 AOF 重写缓冲区,重写完成后追加到新文件。
- 为什么 AOF 恢复比 RDB 慢? AOF 需要逐条解析并执行命令,而 RDB 直接加载二进制数据到内存。
- fork 会阻塞吗? 会,阻塞时间与内存页表大小相关,内存越大阻塞越明显,这也是 Redis 单实例内存不宜过大的原因之一。
总结
RDB 和 AOF 并非对立关系,而是互补关系。RDB 胜在恢复快、体积小,适合备份;AOF 胜在数据安全、实时性强,适合对可靠性要求高的场景。理解两者的底层原理——RDB 的 fork + COW 与 AOF 的 fsync 策略和重写机制——才能在面试中游刃有余,也才能在生产环境中做出正确的架构决策。实际部署中,推荐开启混合持久化,让 RDB 的速度与 AOF 的安全兼而得之。
未经允许不得转载:任鹏个人博客 » Redis 持久化机制:RDB 和 AOF 有什么区别

