Redis 7 持久化机制

Redis 7 持久化机制笔记


一、Redis 7 多部分 AOF 机制

Redis 7 将原来的单文件 appendonly.aof 拆分为三类文件:

文件类型 文件名示例 作用
manifest 文件 appendonly.aof.manifest 清单文件,描述 AOF 的整体组成结构
base 文件 appendonly.aof.1.base.rdb 基础文件,存储全量数据快照
incr 文件 appendonly.aof.1.incr.aof 增量文件,存储 base 文件之后的写命令

1. base 文件的作用

base 文件是 AOF 重写(BGREWRITEAOF)时生成的数据库完整快照:

  • 存储某一时刻的全量数据,作为"基线"
  • 默认使用 RDB 格式,体积小、加载快
  • 作为数据恢复的起点

2. 文件之间的关系

复制代码
时间轴 ──────────────────────────────────────▶

 T0          T1              T2              T3
 │           │               │               │
 ▼           ▼               ▼               ▼

正常运行     触发rewrite      rewrite完成      又触发rewrite
写AOF命令    fork子进程       生成base文件      生成新base文件

incr.1.aof  │               base.rdb        base.rdb
incr.2.aof  │               (RDB+AOF格式)    (RDB+AOF格式)
│           │               │               │
│           │               incr.3.aof      │
│           │               │               incr.4.aof

二、数据恢复顺序与加载流程

1. 恢复优先级总览

复制代码
开启 AOF? ──是──▶ 只加载 AOF 文件
    │
    否
    ▼
存在 RDB? ──是──▶ 加载 RDB 文件
    │
    否
    ▼
空数据库启动

核心原则:AOF 优先于 RDB。 同时开启时只加载 AOF,忽略 RDB。

2. Redis 7 多部分 AOF 的恢复流程

复制代码
① 读取 manifest 文件 ──▶ 获取文件组成清单
② 加载 base 文件 ──▶ 恢复数据库到快照时刻的状态
③ 按顺序加载 base 之后的 incr 文件 ──▶ 回放增量写命令
④ 校验完整性,恢复完成

3. 关键点:只加载 base 之后的 incr 文件

旧的 incr 文件(base 之前)数据已归并进 base,恢复时直接跳过:

复制代码
目录结构:
  appendonly.aof.1.base.rdb      ← 此次 rewrite 的快照
  appendonly.aof.1.incr.aof      ← base 之前的旧 incr(跳过)
  appendonly.aof.2.incr.aof      ← base 之前的旧 incr(跳过)
  appendonly.aof.3.incr.aof      ← base 之后的增量 ✅ 加载
  appendonly.aof.4.incr.aof      ← base 之后的增量 ✅ 加载

恢复顺序:base → incr.3 → incr.4

manifest 文件会明确标注哪些文件需要加载:

复制代码
file seq 1 type b    ← base 文件
file seq 1 type i    ← base 同期的旧 incr(跳过)
file seq 2 type i    ← 新的 incr(加载)
file seq 3 type i    ← 新的 incr(加载)

三、为什么需要加载所有 incr 文件,而不是最后一个

核心原因:incr 文件是增量追加,不是全量覆盖

每个 incr 文件只记录特定时间段内的写命令,彼此不重叠:

复制代码
base.rdb    = T1 时刻的完整快照 {a:1, b:2, c:3}

incr.2.aof  = T1→T2 的写命令
              SET d 4, INCR a, SET e 5

incr.3.aof  = T2→T3 的写命令
              SET f 6, DEL b, INCR a

正确做法:base + incr.2 + incr.3

复制代码
base     → {a:1, b:2, c:3}
incr.2   → 执行 SET d 4, INCR a → {a:2, b:2, c:3, d:4, e:5}
incr.3   → 执行 SET f 6, DEL b  → {a:3, c:3, d:4, e:5, f:6}

错误做法:只读 base + incr.3

复制代码
base     → {a:1, b:2, c:3}
incr.3   → 执行 SET f 6, DEL b → {a:1, c:3, f:6}
丢失了:d、e 两个 key,a 的值也不对

类比:base 是"某个时间点的账户余额",incr 文件是"之后每个月的交易流水"。只知道最后一个月的流水,无法得到正确余额------必须从头算起。


四、混合持久化模式(Hybrid Persistence)

通过 aof-use-rdb-preamble yes 开启(Redis 4.0+)。

1. 正常运行时

日常写入仍然是纯 AOF 格式,与非混合模式完全相同:

复制代码
客户端写入命令 → AOF 缓冲区 → 根据 fsync 策略刷盘写入 incr 文件

2. AOF Rewrite 时(核心差异)

复制代码
① 主进程 fork 子进程
② 子进程写入新的 base 文件:
   ┌─────────────────────────┐
   │  前半部分:RDB 格式       │ ← 全量快照,压缩率高
   │  ████████████████████   │
   ├─────────────────────────┤
   │  后半部分:AOF 格式       │ ← fork 后的增量命令
   │  SET key1 val1          │
   │  INCR counter           │
   │  ...                    │
   └─────────────────────────┘
③ 子进程完成,通知父进程
④ 父进程追加 rewrite 期间缓冲的增量命令
⑤ 原子替换旧文件,更新 manifest

3. 混合模式的数据恢复

复制代码
① 读取 manifest,获取文件列表
② 加载 base 文件
   - 识别文件头 "REDIS" 魔数 → 按 RDB 格式解析前半部分
   - 遇到 RDB EOF 标记 → 切换到 AOF 格式解析后半部分
③ 按顺序加载后续 incr 文件(纯 AOF 格式,逐条回放)
④ 恢复完成

4. 四种持久化方式对比

对比项 纯 RDB 纯 AOF 混合模式 无持久化
数据安全性 可能丢失几分钟 最多丢1秒 最多丢1秒 重启全丢
文件大小 较小
恢复速度 无需恢复
写入性能 不影响 略有开销 略有开销 最快

五、关键配置项速查

配置项 默认值 说明
appendonly no 是否开启 AOF
aof-use-rdb-preamble yes 是否使用混合持久化
appendfsync everysec AOF 刷盘策略
aof-load-truncated yes AOF 截断时是否继续加载
rdbchecksum yes RDB 是否校验 CRC64
auto-aof-rewrite-percentage 100 触发 AOF 重写的增长比例
auto-aof-rewrite-min-size 64mb 触发 AOF 重写的最小文件大小

六、一句话总结

Redis 7 持久化 = base(全量快照地基) + incr(增量日志楼层)。恢复时先加载 base,再按顺序回放 base 之后的 incr 文件。混合模式下 base 前半部分用 RDB 格式加速加载,后半部分和 incr 文件用 AOF 格式保证数据安全。


相关推荐
Geoffwo1 小时前
Oracle MySQL8.0升级8.4,无感升级数据库
数据库·oracle
u0110225121 小时前
如何自定义查询历史记录面板的展示风格_时间轴样式设计
jvm·数据库·python
2301_769340671 小时前
HTML怎么实现快捷跳转顶部_HTML固定悬浮锚点按钮【介绍】
jvm·数据库·python
m0_609160491 小时前
MySQL如何限制触发器递归调用的深度_防止触发器死循环方法
jvm·数据库·python
呼Lu噜1 小时前
基于C#的ASP.NET Core中分析async、await的使用场景
数据库·c#·asp.net
李白的天不白1 小时前
大规模请求数据并发问题
java·前端·数据库
zjy277771 小时前
Golang bcrypt如何加密密码_Golang密码加密教程【收藏】
jvm·数据库·python
万邦科技Lafite1 小时前
API接口一键获取商品评论,根据商品评论分析客户画像
linux·服务器·数据库·windows·microsoft·电商开放平台
phltxy2 小时前
Redis 核心数据类型之 String 详解
数据库·redis·bootstrap