前置知识: Redis

混合持久化

4 min高级

Redis混合持久化:RDB+AOF组合方案、加载流程、配置与性能权衡

1. 混合持久化概述

混合持久化是 Redis 4.0 引入的持久化方案,结合了 RDB 的高效恢复和 AOF 的数据安全性。在 AOF 重写时,将当前数据以 RDB 格式写入 AOF 文件开头,后续增量命令仍以 AOF 格式追加。

核心思想:

flowchart LR
    M[混合 AOF 文件] --> R[RDB 格式<br/>全量快照] --> A[AOF 格式<br/>增量命令]

7.0 multi-part AOF 之后:上述「RDB 开头 + AOF 增量」拆成了两个文件—— RDB 快照独立为 *.base.rdb(base),增量命令在 *.incr.aof(incr), 由 manifest 清单串联,本质与混合持久化思想一致,加载顺序不变 (先 base 后 incr)。4.x~6.x 才是真正的「单文件混合」。

2. 混合持久化工作原理

2.1 重写时的文件生成

当 AOF 重写触发时:

  1. 子进程将当前内存数据以 RDB 二进制格式写入临时文件开头
  2. 重写期间的新命令以 AOF 文本格式追加到临时文件末尾
  3. 重写完成后,临时文件替换旧 AOF 文件
重写过程:

旧 AOF 文件:
  SET key1 val1
  SET key2 val2
  DEL key1
  SET key3 val3
  SET key2 newval2
  ...(数百万条命令)

新 AOF 文件(混合格式):
  [RDB 二进制数据:key2=newval2, key3=val3, ...]
  SET key4 val4        ← 重写期间的增量命令
  SET key5 val5
  ...

2.2 文件体积对比

假设 Redis 中有 100 万个 key,每个 key 平均 100 字节:

格式估算大小说明
纯 AOF~200 MB每条命令的文本表示
纯 RDB~100 MB压缩二进制格式
混合 AOF~100 MB + 增量RDB 部分 + 少量增量 AOF

混合 AOF 的体积约为纯 AOF 的 50%~70%,接近 RDB 的紧凑程度。

3. 混合持久化加载流程

Redis 启动加载混合 AOF 文件时:

1. 读取 AOF 文件头部
2. 检测到 RDB 格式标记(REDIS 前缀)
3. 以 RDB 方式加载前半部分(快速恢复全量数据)
4. 以 AOF 方式重放后半部分(恢复增量数据)
5. 加载完成,开始接受请求

详细流程:

flowchart TD
    A[加载混合 AOF 文件] --> B[读取前 9 字节<br/>判断是否为 RDB 格式]
    B -->|纯 AOF| C[逐条重放命令]
    B -->|混合格式| D[RDB 加载全量数据]
    D --> E[AOF 重放增量命令]
    C --> F[加载完成]
    E --> F

3.1 格式检测

Redis 通过检查 AOF 文件开头来判断格式:

  • 以 REDIS 开头 → RDB 格式(混合 AOF)
  • 以 * 开头 → 纯 AOF 格式(RESP 协议)
// 伪代码
int loadAppendOnlyFile(char *filename) {
    if (starts_with(buf, "REDIS")) {
        // 混合格式:先加载 RDB 部分
        rdbLoadRio(&rdb);
        // 再加载 AOF 增量部分
        while (readCommand(&cmd)) {
            executeCommand(cmd);
        }
    } else {
        // 纯 AOF 格式
        while (readCommand(&cmd)) {
            executeCommand(cmd);
        }
    }
}

4. 配置与启用

4.1 开启混合持久化

# redis.conf
appendonly yes                    # 开启 AOF
aof-use-rdb-preamble yes          # 开启混合持久化(4.0 引入,7.0 起默认 yes)
# 运行时修改
CONFIG SET aof-use-rdb-preamble yes

4.2 关键配置项

# AOF 基础配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

# 混合持久化开关
aof-use-rdb-preamble yes

# 重写触发条件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

4.3 版本兼容性

Redis 版本混合持久化支持默认值
< 4.0不支持-
4.0支持no
5.0+支持yes
7.0+支持(MP-AOF)yes

注意:Redis 7.0 引入了 Multi Part AOF(MP-AOF),将 AOF 拆分为基础文件(BASE)和增量文件(INCR),进一步优化了混合持久化的实现。

5. 三种持久化方案对比

特性纯 RDB纯 AOF混合持久化
数据安全性低(分钟级丢失)高(秒级丢失)高(秒级丢失)
恢复速度快慢较快
文件体积最小最大中等
性能影响fork 开销写入开销两者兼具
可读性不可读可读部分可读
兼容性所有版本所有版本Redis 4.0+

5.1 恢复速度对比

对于 1000 万个 key 的数据集:

方案恢复时间说明
纯 RDB~10 秒直接加载二进制
纯 AOF~120 秒逐条重放命令
混合 AOF~15 秒RDB 快速加载 + 少量 AOF 重放

混合持久化的恢复速度约为纯 AOF 的 8~10 倍,接近纯 RDB 的水平。

6. Redis 7.0 Multi Part AOF

Redis 7.0 对 AOF 进行了重大重构,引入 Multi Part AOF(MP-AOF):

6.1 文件结构

flowchart TD
    T0["appendonlydir/"]
    T1["appendonly.aof.1.base.rdb       # BASE 文件(RDB 格式)"]
    T2["appendonly.aof.1.incr.aof       # INCR 文件(增量 AOF)"]
    T3["appendonly.aof.2.incr.aof       # INCR 文件(重写期间增量)"]
    T4["appendonly.aof.manifest         # 清单文件"]
    T0 --> T1
    T0 --> T2
    T0 --> T3
    T0 --> T4

6.2 Manifest 文件

file appendonly.aof.1.base.rdb seq 1 type b
file appendonly.aof.1.incr.aof seq 1 type h
file appendonly.aof.2.incr.aof seq 2 type h

6.3 重写流程变化

  1. 创建新的 BASE 文件(RDB 格式)
  2. 重写期间的增量写入新的 INCR 文件
  3. 更新 manifest 文件(原子替换)
  4. 异步删除旧的 BASE 和 INCR 文件

优势:

  • 不再需要将增量命令追加到重写后的文件
  • 重写完成后只需更新 manifest,无需修改数据文件
  • 减少了重写期间的内存占用

7. 最佳实践

7.1 生产环境推荐配置

appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

7.2 场景选择

场景推荐方案理由
数据安全优先混合持久化兼顾安全和恢复速度
纯缓存禁用持久化最大化性能
备份为主RDB + 定时归档文件紧凑,便于传输
金融/支付混合 + always fsync最高数据安全

7.3 监控要点

# 查看持久化状态
INFO Persistence

# 关键指标
# aof_current_size: 当前 AOF 文件大小
# aof_base_size: 上次重写后的大小
# aof_rewrite_in_progress: 是否正在重写
# aof_last_bgrewrite_status: 上次重写状态