Redis 持久化机制:RDB 与 AOF 详解

Redis 是一个内存数据库,数据主要存储在内存中,因此一旦进程退出或服务器宕机,数据就会丢失。为了解决这个问题,Redis 提供了两种持久化方式:RDB(Redis Database)AOF(Append Only File) ,以及从 4.0 版本开始引入的混合持久化


一、RDB 持久化

RDB 是一种快照(snapshot) 持久化方式:在指定时间间隔内,将内存中的数据集以二进制形式写入磁盘,生成一个 dump.rdb 文件。

1.1 触发机制

  • 手动触发

    • SAVE:阻塞 Redis 主进程,直到 RDB 文件创建完成。生产环境不建议使用。
    • BGSAVE:fork 一个子进程负责创建 RDB 文件,主进程继续处理客户端请求(仅 fork 期间短暂阻塞)。
  • 自动触发

    通过 redis.conf 配置 save 指令,例如:

    bash 复制代码
    save 900 1      # 900 秒内至少有 1 次修改
    save 300 10     # 300 秒内至少有 10 次修改
    save 60 10000   # 60 秒内至少有 10000 次修改

    满足任一条件,Redis 就会自动执行 BGSAVE

  • 其他自动触发场景

    • 主从复制全量同步时,主节点会执行 BGSAVE 生成 RDB 并发送给从节点。
    • shutdown 命令且未开启 AOF 时,会执行一次 SAVE
    • debug reload 命令也会触发 RDB 保存。

1.2 文件格式

RDB 文件是一个经过压缩的二进制文件,结构大致如下:

lua 复制代码
+----------+---------+-----------+-----------+ ... +--------+----------+
| "REDIS"  | RDB_VER |  AUX 段   |  数据库段  | ... |  EOF   | CHECKSUM |
+----------+---------+-----------+-----------+ ... +--------+----------+
  • 魔数(Magic Number) :5 字节 "REDIS",用于快速识别 RDB 文件。
  • 版本号(RDB Version) :4 字节 ASCII 数字,例如 "0009"(v9),表示 RDB 格式版本。当前最新版本为 10(Redis 7.0+ 使用 v10)。
  • AUX 字段(可选) :存储键值对形式的元信息,例如 redis-verredis-bitsctimeused-mem 等。
  • 数据库段:依次存储每个非空数据库的数据,每个数据库包含若干键值对。
  • EOF 标记 :固定值 0xFF 1 字节,表示数据部分结束。
  • 校验和(Checksum) :8 字节无符号整数,CRC64 校验和,用于验证文件完整性(Redis 5.0+ 强制启用)。

1.3 优缺点

优点 缺点
文件紧凑:二进制文件体积小,适合备份和灾难恢复。 可能丢失数据:若在两次快照之间发生宕机,最后一次快照后的所有修改都会丢失。
恢复速度快:直接加载 RDB 到内存,比 AOF 的日志重放快得多。 fork 开销:当数据集较大时,fork 子进程可能耗时,导致主进程短暂阻塞(尤其是大内存服务器)。
对性能影响相对小:子进程执行 I/O,主进程仅 fork 时阻塞。 不实时:无法做到秒级持久化。

二、AOF 持久化

AOF 以追加写日志的方式记录每个写操作(以 Redis 协议格式),服务器启动时通过重放日志来重建数据。

2.1 工作流程

  1. 命令追加 :所有写命令以文本协议格式追加到 aof_buf 缓冲区。
  2. 文件同步:根据配置的策略,将缓冲区内容同步到磁盘的 AOF 文件。
  3. 文件重写 :AOF 文件过大时,后台重写(BGREWRITEAOF)生成一个最小命令集的新 AOF 文件,覆盖旧文件。
  4. 重启加载:服务器启动时优先加载 AOF 文件(如果同时开启 RDB 和 AOF,则 AOF 优先)来恢复数据。

2.2 同步策略(appendfsync

配置值 行为 性能 安全性
always 每次写命令都调用 fsync 同步到磁盘 最慢 最多丢失一个命令(已写入但未 fsync 的数据可能丢失,但 always 下每个命令后都 fsync,几乎不丢失)
everysec 每秒执行一次 fsync,可能将多个命令合并在一次同步中 折中 最多丢失最近一秒的数据(默认推荐)
no 由操作系统决定何时刷盘(通常 30 秒左右) 最快 可能丢失大量数据

2.3 AOF 重写机制

随着写操作增多,AOF 文件会越来越大。重写的作用是:

  • 去除冗余命令(如多次 INCR 合并为一条 SET)。
  • 删除已超时或已被删除的 key 相关命令。
  • 生成一个最小且完整的数据集命令集合。

重写过程:

  1. 主进程 fork 一个子进程。
  2. 子进程根据当前内存数据生成新的 AOF 文件(先写到临时文件)。
  3. 主进程在此期间继续处理请求,并将新写入命令同时记录到旧的 AOF 缓冲区重写缓冲区
  4. 子进程完成后,主进程将重写缓冲区中的增量命令追加到新 AOF 文件末尾。
  5. 用新 AOF 文件原子替换旧文件。

触发重写的条件(redis.conf):

arduino 复制代码
auto-aof-rewrite-percentage 100   # 文件大小比上次重写后增长 100%
auto-aof-rewrite-min-size 64mb    # 最小体积达到 64MB 才触发

2.4 优缺点

优点 缺点
数据安全性高everysec 下最多丢 1 秒数据,always 下几乎不丢数据。 文件体积大:AOF 是文本格式,且记录所有写操作,通常比 RDB 大。
可读性强 :AOF 文件是纯文本,即使误操作(如 FLUSHALL)也可以手动编辑文件删除最后一两条命令后恢复。 恢复速度慢:重启时需要逐条执行命令,比加载 RDB 慢很多。
自动重写:可以控制文件大小,避免无限增长。 对性能有一定影响 :尤其是 always 策略,磁盘 I/O 开销大。

三、RDB vs AOF 对比总结

对比项 RDB AOF
原理 定期内存快照 记录所有写命令日志
数据完整性 可能丢失最后一次快照后的数据 everysec 丢 1 秒,always 几乎不丢
文件大小 较小(二进制压缩) 较大(文本,但重写后可缩小)
恢复速度 快(直接加载数据) 慢(重放命令)
对性能影响 fork 子进程时短暂阻塞,I/O 压力小 写入和 fsync 增加磁盘 I/O
适用场景 对数据丢失不敏感、追求快速重启和备份 对数据安全要求高,如金融、交易系统
可读性 不可读 可读,便于分析或紧急修复

四、混合持久化(Redis 4.0+)

为了结合 RDB 和 AOF 的优点,Redis 4.0 引入了混合持久化。当 AOF 重写时,不再生成纯文本命令,而是先生成当前内存数据的 RDB 快照(二进制格式),再追加重写期间的增量命令(以 AOF 格式)。最终生成的 AOF 文件结构为:

css 复制代码
[RDB 数据] [AOF 增量命令]
  • 优点:重启恢复时,先快速加载 RDB 部分,再执行少量 AOF 命令,既快又完整。
  • 开启方式aof-use-rdb-preamble yes(Redis 5.0+ 默认开启)。
  • 兼容性:旧版本 Redis 无法识别这种混合格式,但会忽略 RDB 部分直接读取 AOF 命令(可能导致数据丢失),因此升级后不建议降级。

五、如何选择与最佳实践

  1. 仅用作缓存,允许大量数据丢失

    → 可以不开启持久化,或只开 RDB(如每 15 分钟一次)。

  2. 既要性能,又不想丢失太多数据

    → 推荐 RDB + AOF(appendfsync everysec)同时开启。恢复时 AOF 优先。

    → 从 Redis 4.0 起开启混合持久化。

  3. 数据安全性极高(如金融交易)

    → 开启 AOF always,但性能会明显下降。可考虑使用 SSD 并优化 fsync 策略。

  4. 大数据集恢复速度要求高

    → 优先使用 RDB 或混合持久化。

  5. 主从复制环境

    • 主节点可不开持久化,但从节点必须开启持久化(否则主节点重启后从节点会清空数据)。
    • 主节点关闭持久化可提高性能,但需确保从节点有完整数据备份。
  6. 定期备份

    • RDB 文件非常适合异地备份(每天 cp 或 scp 到其他机器)。
    • 如果只用 AOF,也建议定期 BGREWRITEAOF 减少文件大小。

六、常见问题与故障处理

  • RDB 文件损坏redis-check-rdb 工具可以检查并尝试修复。
  • AOF 文件损坏redis-check-aof --fix 可截断损坏部分。
  • fork 子进程失败 :检查系统内存是否不足(overcommit_memory 设置),或使用 vm.overcommit_memory=1
  • AOF 文件过大导致重启缓慢 :开启自动重写,或手动执行 BGREWRITEAOF
  • 突然断电后 AOF 不完整 :Redis 启动时会自动截断到最后一个完整命令,也可用 redis-check-aof 修复。

总结

  • RDB 适合备份、快速恢复、对数据丢失容忍度较高的场景。
  • AOF 适合高数据安全性、可接受恢复时间稍长的场景。
  • 混合持久化 结合两者优点,是生产环境的推荐配置。

没有完美的持久化方案,需要根据业务对数据一致性、性能、恢复速度的权衡来选择合适的策略。通常建议同时开启 RDB 和 AOF(everysec) ,并开启混合持久化,同时配合定期备份和监控。

相关推荐
身如柳絮随风扬2 小时前
Redis 如何统计独立用户访问量?
redis
脑子加油站2 小时前
OpenEuler24.03 分布式配置redis 集群
数据库·redis·分布式·php·nginx代理
ZC跨境爬虫4 小时前
纯requests+Redis实现分布式爬虫(可视化4终端,模拟4台电脑联合爬取)
redis·分布式·爬虫·python
Cat_Rocky14 小时前
redis哨兵模式
数据库·redis
披着羊皮不是狼18 小时前
(7)为 RAG 系统接入 Redis Stack 实现向量持久化
数据库·redis·缓存
XDHCOM19 小时前
Docker怎么设置Redis?
redis·docker·容器
ruan11451421 小时前
Redis--个人学习记录
数据库·redis·学习
Micro麦可乐21 小时前
Redis只会用来做缓存?解锁Redis非缓存的九个应用场景,90%程序员不知道的隐藏技能
数据库·redis·缓存·消息队列·分布式锁·延迟队列·布隆过滤器
21号 11 天前
10.Redis 缓存
数据库·redis·缓存