💾

Redis 数据持久化:快照 vs 写日志

Redis 为何能作为"保险箱"?它有两种截然不同的数据持久化策略——RDB 定时快照和 AOF 持续记录。两者如何工作?各有何优劣?接下来用动态流程图和动画为你讲清楚。

RDB

Redis Database Backup

通过 fork 子进程,在指定时间点生成数据库的完整快照,dump 为 .rdb 文件。数据以二进制格式紧凑存储,是 Redis 最早的持久化方案。

定期快照 fork子进程 二进制压缩 全量备份
AOF

Append Only File

将每一个写操作命令追加记录到 .aof 文件,类似数据库的 WAL(预写日志)。服务重启时重放日志恢复数据,实现更精细的数据保护。

写命令追加 重放恢复 可配置策略 增量备份
🔴 RDB 工作流程
通过 fork 子进程,在内存中生成一份数据快照并持久化

RDB 快照生成流程

触发条件满足
定时器 / BGSAVE / SHUTDOWN / AOF重写
🔧
检查配置
save / stop-writes-on-bgsave-error
🍴
fork() 子进程
复制页表,COW机制启动
📋
主进程继续服务
处理客户端请求,正常读写
🗂️
子进程遍历内存
读取 Redis 对象树结构
📦
序列化写入
生成 RDB 二进制格式
💾
写入临时文件
dump.rdb.tmp
🔄
原子替换
rename dump.rdb
📣
发送通知
Redis通知子进程退出状态
恢复继续服务
主进程恢复客户端请求
⚠️ 关键机制
COW (Copy-On-Write)
fork 时共享主进程的页表(copy-on-write)。fork 瞬间极快,之后每次主进程写入时才真正复制内存页。
内存峰值
数据量越大,fork 耗时越高,且 COW 期间所有被修改的页都需要复制,可能占用 2 倍内存。
🔵 AOF 工作流程
将每个写命令实时追加记录到文件,服务重启时重放命令恢复数据

AOF 写入与恢复流程

写入流程(正常运行时)
📥
客户端写命令
SET / HSET / LPUSH...
🔌
主线程处理
执行命令 + 更新内存
📝
写入 AOF 缓冲区
aof_buf (C字符串)
⚙️
根据策略刷盘
Always / Everysec / No
📄
追加到 appendonly.aof
顺序写入磁盘
重写流程(AOF 文件压缩)
📏
AOF 体积过大
bgrewriteaof 触发 / auto-aof-rewrite-percentage
🍴
fork() 子进程
同 RDB,COW 机制
🧹
子进程重写
将多条命令合并为最终状态
📤
子进程写临时文件
temp-rewriteaof-*.aof
🔄
原子替换原AOF
rename 原子替换
恢复流程(Redis 重启时)
🚀
Redis 启动
检测到 aof 文件存在
📖
加载 AOF 文件
读取 appendonly.aof
▶️
重放命令
逐条执行 AOF 中命令
恢复完成
内存数据恢复至最新

⚡ 动态演示:数据随时间的命运

📸 RDB 快照时刻(每 60 秒触发一次 save)
快照1
快照2
T=0s: 快照保存数据 T=60s: 崩溃,丢失 60 秒数据 T=60s: 快照2 保存
📝 AOF 追加记录(每秒同步一次 Everysec 策略)
AOF 持续记录所有写命令
崩溃后只需重放最后 1 秒内的操作,数据几乎零丢失(Everysec)
📋 实时写命令日志
每个操作命令都被追加记录到 AOF 文件,RDB 只在快照时刻记录当前状态
⚙️ AOF 同步策略对比
appendfsync 参数控制何时将 aof_buf 刷入磁盘
always
每个命令都同步

每个写命令执行后立即调用 fsync 刷盘。最多丢失正在执行的那一条命令。

✓ 最高安全性
⚠ 性能开销最大,每次写都同步磁盘
everysec
每秒同步(默认)

每秒调用一次 fsync,最多丢失 1 秒内的操作。性能与安全性的最佳平衡。

✓ 推荐策略
Redis 默认配置,适合大多数场景
no
由系统决定

不主动同步,由操作系统决定何时刷盘。性能最好,但最多可能丢失未知时间窗口的数据。

⚠ 最大风险
依赖操作系统 buffer 策略
📊 核心对比
一图看懂 RDB 和 AOF 的本质差异
对比维度 🔴 RDB 🔵 AOF
持久化方式 定时生成全量快照文件 实时追加每个写命令到日志
文件格式 二进制压缩格式(.rdb),体积小 明文命令格式(.aof),可读但体积大
数据安全性 ⚠ 可能丢失最近一次快照后的数据
(最多一个快照周期的数据)
✓ 更高(取决于同步策略)
Everysec 最多丢 1 秒
恢复速度 ✅ 极快(直接加载二进制) ⚠ 较慢(需逐条重放命令)
文件大小 ✅ 小(压缩二进制) ⚠ 大(纯文本,冗余信息多)
对性能影响 fork + COW,CPU 开销较大 写入缓冲区开销小,但刷盘会阻塞
资源消耗 fork 时峰值约 2 倍内存 日志持续写入磁盘
启动优先级 同时启用时,Redis 优先加载 AOF(数据更新)
适用场景 数据量中等、可接受分钟级丢失、
需要快速冷备份
数据敏感、要求更高持久化可靠性

🎯 最佳实践:RDB + AOF 混合持久化

1
启用 RDB

配置定期快照,作为冷备和快速恢复底座

2
启用 AOF

使用 everysec 策略,保障数据接近实时持久化

3
AOF 重写

定期触发 bgrewriteaof,压缩日志体积

4
监控容量

监控 AOF 膨胀,及时调整重写策略

🔴 RDB — 定时快照

  • fork 子进程生成二进制快照
  • 文件小、恢复快
  • 可能丢失快照周期内的数据
  • fork 时有 2 倍内存峰值风险
  • 适合做冷备份和快速恢复

🔵 AOF — 写日志

  • 追加记录每个写命令
  • 数据安全性更高(可配置)
  • 文件较大,需定期重写压缩
  • 重放恢复速度慢于 RDB
  • everysec 是性能与安全的最佳平衡
💡 一句话总结
RDB 像"定时拍照"——简单高效,但两次快门之间发生的事情全丢了。
AOF 像"实时录像"——记录每一帧,数据更完整,但需要定期"剪辑"(重写)防止文件过大。
生产环境推荐 两者同时启用,取长补短。