Redis 持久化 RDB 和 AOF 有什么区别?

2025年 阅读约 15 分钟 面试指南 · Redis

深入解析Redis持久化机制:RDB快照(bgsave子进程、Copy-On-Write)、AOF日志(always/everysec/no三种策略)、混合持久化(Redis 4.0+)、AOF Rewrite重写原理,附面试模拟问答。

一句话总结

RDB(快照):某个时刻的全量数据快照,二进制文件,恢复快但可能丢数据。通过 bgsave 子进程 + Copy-On-Write 实现不阻塞主进程。AOF(追加日志):记录每条写命令,数据安全但文件大恢复慢。混合持久化(Redis 4.0+):RDB 全量 + AOF 增量,兼顾恢复速度和数据安全。生产环境推荐混合持久化

初级理解

RDB vs AOF 对比

对比维度RDBAOF
原理全量快照追加写命令
文件大小小(二进制压缩)大(文本命令)
恢复速度慢(重放命令)
数据安全可能丢最后一次快照后的数据最多丢 1 秒(everysec)
对性能影响fork 子进程时短暂阻塞持续写磁盘 IO
默认开启✅ 是❌ 否
# RDB 触发方式 # 1. 自动触发(配置 save 规则) save 900 1 # 900 秒内至少 1 次修改 save 300 10 # 300 秒内至少 10 次修改 save 60 10000 # 60 秒内至少 10000 次修改 # 2. 手动触发 SAVE # 阻塞主进程(不推荐) BGSAVE # 子进程异步执行(推荐) # AOF 配置 appendonly yes appendfsync always # 每次写都刷盘(最安全,最慢) appendfsync everysec # 每秒刷一次(推荐,最多丢 1 秒) appendfsync no # 由 OS 决定(最快,最不安全)
一句话总结:RDB 全量快照恢复快但可能丢数据,AOF 增量日志数据安全但恢复慢。

中级深入

RDB — bgsave 与 Copy-On-Write

bgsave 通过 fork() 创建子进程,利用操作系统的 Copy-On-Write(写时复制)机制:

1. fork() 时,子进程共享父进程的内存页(只读)

2. 父进程继续处理写请求时,被修改的内存页会被复制一份

3. 子进程读取的是 fork 时刻的数据快照,不受后续修改影响

# bgsave 流程 # 1. Redis 主进程 fork() 子进程 # 2. 子进程遍历内存数据,写入临时 RDB 文件 # 3. 子进程完成后,用临时文件替换旧 RDB 文件 # 4. 主进程继续处理请求(Copy-On-Write 保证数据一致性) # 注意: # fork() 会阻塞主进程,阻塞时间取决于内存大小 # 10GB 内存约阻塞 100ms # 所以 RDB 不适合频繁执行

AOF Rewrite — 压缩 AOF 文件

AOF 文件会越来越大,需要定期重写(Rewrite)来压缩。Rewrite 不是分析旧 AOF 文件,而是读取当前内存数据,生成等价的 SET 命令

# AOF Rewrite 示例 # 原始 AOF: SET count 1 INCR count # count=2 INCR count # count=3 INCR count # count=4 # Rewrite 后: SET count 4 # 一条命令等价于上面 4 条 # 触发条件(自动) auto-aof-rewrite-percentage 100 # AOF 文件增长 100% auto-aof-rewrite-min-size 64mb # AOF 文件最小 64MB # 手动触发 BGREWRITEAOF

混合持久化(Redis 4.0+)

AOF Rewrite 时,将当前内存数据以 RDB 格式写入 AOF 文件头部,后续增量以 AOF 格式追加。恢复时先加载 RDB 部分(快),再重放 AOF 部分(数据全)。

# 混合持久化配置 aof-use-rdb-preamble yes # Redis 5.0 默认开启 # 混合文件结构 # [RDB 二进制数据][AOF 增量命令] # 恢复流程: # 1. 加载 RDB 部分(快速恢复大部分数据) # 2. 重放 AOF 部分(恢复增量数据) # 兼顾 RDB 的恢复速度和 AOF 的数据安全
中级要点:bgsave 用 Copy-On-Write 不阻塞主进程;AOF Rewrite 压缩命令;混合持久化兼顾速度和安全。

高级拓展

持久化策略选择

场景推荐方案原因
纯缓存(可丢)不持久化性能最优
数据不敏感RDB恢复快,可接受少量丢失
数据敏感AOF everysec最多丢 1 秒
生产推荐混合持久化恢复快 + 数据安全

持久化对性能的影响

# RDB 影响 # - fork() 阻塞:内存越大阻塞越久 # - Copy-On-Write 内存开销:写多时可能额外占用大量内存 # 建议:预留 50% 内存给 COW # AOF 影响 # - always: 每次写都 fsync,性能最差 # - everysec: 每秒 fsync,性能影响小(推荐) # - no: 不主动 fsync,性能最好但不安全 # 优化建议 # 1. 关闭 THP(Transparent Huge Pages) # 2. 设置 no-appendfsync-on-rewrite yes(Rewrite 时不 fsync) # 3. 合理设置 auto-aof-rewrite 参数

实战场景

场景:Redis 数据恢复

# 1. 确认持久化文件 ls -la /var/lib/redis/ # dump.rdb: RDB 文件 # appendonly.aof: AOF 文件 # 2. 检查文件完整性 redis-check-rdb dump.rdb redis-check-aof --fix appendonly.aof # 3. 恢复步骤 # 停止 Redis systemctl stop redis # 替换持久化文件 cp backup/dump.rdb /var/lib/redis/ # 启动 Redis(自动加载 RDB/AOF) systemctl start redis # 4. 验证数据 redis-cli DBSIZE

面试模拟

面试官:RDB 和 AOF 有什么区别?怎么选?

你:RDB 是全量快照,二进制文件小恢复快,但可能丢数据;AOF 是追加命令日志,数据安全但文件大恢复慢。生产环境推荐混合持久化(Redis 4.0+),AOF Rewrite 时将内存数据以 RDB 格式写入,兼顾恢复速度和数据安全。

面试官:bgsave 的原理是什么?

你:bgsave 通过 fork() 创建子进程,利用操作系统的 Copy-On-Write 机制。fork 时子进程共享父进程内存页(只读),父进程继续处理写请求时,被修改的内存页会被复制。子进程读取的是 fork 时刻的数据快照,不受后续修改影响。注意 fork 会短暂阻塞主进程,阻塞时间取决于内存大小。