3. Redis 持久化机制:RDB快照原理、AOF日志原理、混合持久化策略

Redis 作为内存数据库,其数据全部存储在 RAM 中。一旦进程退出或机器宕机,内存数据将全部丢失。持久化机制是 Redis 提供数据安全保障的核心能力,也是构建高可用缓存架构的基石。本章深入剖析 RDB 快照、AOF 日志以及混合持久化三种策略的原理、配置与选型。

3.1 RDB 快照原理

RDB(Redis Database)持久化通过创建数据集的时间点快照(Point-in-Time Snapshot)来实现数据备份。它采用二进制压缩格式,文件体积小,适合用于全量备份、灾难恢复及数据迁移。

3.1.1 触发机制

RDB 的触发方式分为手动触发和自动触发两类:

触发方式 命令/配置 说明
手动触发 SAVE 同步阻塞,由主进程执行快照生成,期间不处理任何客户端请求
手动触发 BGSAVE 异步非阻塞,主进程 fork 子进程,由子进程负责快照写入
自动触发 save m n 在 m 秒内,如果数据集发生 n 次修改,则自动执行 BGSAVE
自动触发 shutdown 关闭服务器时,如果没有开启 AOF,则自动执行一次 SAVE
自动触发 主从复制全量同步 主节点在首次连接或复制中断时,自动生成 RDB 文件发送给从节点

3.1.2 核心流程:Copy-On-Write 写时复制

RDB 异步持久化的核心依赖 Linux 系统的 Copy-On-Write(COW) 机制。当执行 BGSAVE 时,主进程通过 fork() 系统调用创建一个子进程。子进程与主进程共享同一份内存页表,此时物理内存并未复制。只有当主进程在快照生成期间需要修改某个内存页时,才会复制该页到新的内存地址,从而保证子进程看到的是一份完整且一致的数据快照。

RDB 快照核心流程(COW 写时复制) 主进程(Redis Server) 子进程(fork 生成) 共享内存页表 初始时父子进程 指向同一物理内存 主进程写操作触发 COW 复制修改页到新地址 子进程始终看到 fork 时刻的完整数据 fork() RDB 快照文件 子进程遍历共享内存,写入快照 主进程写操作

3.1.3 RDB 文件结构

RDB 文件采用紧凑的二进制格式,主要包含以下部分:

  • 魔数(Magic Number):固定为 "REDIS",用于文件类型识别。
  • RDB 版本号:标识文件格式版本。
  • 辅助字段:包含 Redis 版本、创建时间、数据集大小等元信息。
  • 数据库数据:按数据库编号存储键值对,每个键值对包含类型编码、过期时间、键和值。
  • 校验和(Checksum):文件末尾的 CRC64 校验码,用于检测文件完整性。

3.2 AOF 日志原理

AOF(Append Only File)持久化以日志形式记录每次写操作命令,重启时通过回放所有命令来重建数据集。相比 RDB 的快照方式,AOF 提供了更高的数据安全性,但文件体积更大,恢复速度较慢。

3.2.1 写回策略

AOF 的持久化时机由 appendfsync 配置控制,决定了数据在发生宕机时的丢失量:

配置值 行为 数据安全性 性能影响
always 每次写命令执行后,立即同步到磁盘 极高,最多丢失一个命令 最慢,频繁磁盘 I/O
everysec 每秒将缓冲区数据同步一次到磁盘 较高,最多丢失 1 秒数据 适中,推荐生产环境使用
no 由操作系统决定何时刷盘 低,可能丢失大量数据 最快,但不可控

3.2.2 AOF 重写机制

随着运行时间增长,AOF 文件会不断膨胀。AOF 重写(Rewrite)通过读取当前内存中的数据状态,生成一组最小化的写命令来重建整个数据集,从而压缩文件体积。重写过程同样基于 子进程 + COW 实现,主进程在此期间继续处理请求,并将新写入的命令同时缓存到 AOF 重写缓冲区,待子进程完成后一并追加到新 AOF 文件中。

设计要点: AOF 重写不是对旧文件的修改,而是创建一个全新的、体积更小的 AOF 文件。重写期间主进程不会阻塞,但会额外消耗内存用于 COW 复制。

3.3 混合持久化策略

Redis 4.0 引入了混合持久化(Mixed Persistence),结合 RDB 和 AOF 的优点。当开启 aof-use-rdb-preamble yes 时,AOF 文件的前半部分是一个完整的 RDB 快照,后半部分追加 RDB 快照生成之后的增量 AOF 日志。

3.3.1 混合持久化文件结构

混合持久化 AOF 文件结构 RDB 快照(全量数据) 二进制格式,体积小,加载快 增量 AOF 日志 文本格式,记录 RDB 之后的写操作 重启恢复时:先加载 RDB 部分快速重建基础数据 再回放 AOF 增量日志,恢复到最新状态

3.3.2 三种持久化策略对比

对比维度 RDB AOF 混合持久化
数据安全性 低,可能丢失上次快照后的所有数据 高,最多丢失 1 秒数据(everysec) 高,与 AOF 一致
文件体积 小,二进制压缩 大,文本命令累积 中等,RDB 部分压缩了基础数据
恢复速度 快,直接加载二进制快照 慢,逐条回放命令 快,RDB 快速加载 + 少量增量回放
对性能影响 BGSAVE 时 fork 子进程,COW 可能增加内存开销 写回策略影响写性能,重写时 fork 子进程 重写时生成 RDB 前缀,开销略高于纯 AOF 重写
适用场景 数据可容忍丢失、快速恢复、备份迁移 数据安全性要求高、允许稍慢的恢复 生产环境推荐,兼顾安全与恢复速度

3.4 生产配置建议

推荐配置: 开启混合持久化(aof-use-rdb-preamble yes),AOF 写回策略设为 everysec,同时保留 RDB 自动触发(如 save 900 1)作为兜底备份。这样既能保证秒级数据丢失容忍度,又能利用 RDB 快速恢复的优势。

3.4.1 关键配置项

# 开启 AOF
appendonly yes
# AOF 写回策略:每秒同步
appendfsync everysec
# 开启混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes
# AOF 重写触发条件:文件增长 100% 且大于 64MB
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# RDB 自动触发条件(兜底)
save 900 1
save 300 10
save 60 10000
注意: 在开启 AOF 的情况下,Redis 重启时优先使用 AOF 文件恢复数据,因为 AOF 的数据完整性更高。如果 AOF 文件损坏,可以尝试使用 redis-check-aof --fix 工具修复。