@@ -296,9 +296,19 @@ Redis 7.0 版本之后,AOF 重写机制得到了优化改进。下面这段内
296296
297297** 相关 issue** :[ Redis AOF 重写描述不准确 #1439 ] ( https://github.com/Snailclimb/JavaGuide/issues/1439 ) 。
298298
299- ### AOF 校验机制了解吗 ?
299+ ### AOF 文件如何验证数据完整性 ?
300300
301- 纯 AOF 模式下,Redis 不会对整个 AOF 文件使用校验和(如 CRC64),而是通过逐条解析文件中的命令来验证文件的有效性。如果解析过程中发现语法错误(如命令不完整、格式错误),Redis 会终止加载并报错,从而避免错误数据载入内存。
301+ ** 核心结论** :纯 AOF 文件** 没有** 校验和机制,仅通过逐条命令解析验证;CRC64 校验和仅存在于混合持久化文件的 ** RDB 部分** 。
302+
303+ #### 纯 AOF 模式:无校验和,仅语法解析
304+
305+ 纯 AOF 文件不会对整体或单条命令计算 CRC64 校验和,而是通过逐条解析文件中的命令来验证有效性。
306+
307+ ** 为什么没有校验和?**
308+
309+ AOF 是高频追加写入的文本日志。如果每次追加命令都要重新计算整个文件的 CRC64 校验和,会对主线程的 CPU 和磁盘 I/O 造成严重拖累。因此 Redis 选择了更轻量的方式:重启加载时逐条读取并解析命令语法。
310+
311+ 如果解析过程中发现语法错误(如命令不完整、格式错误),Redis 会终止加载并报错。
302312
303313> ** 尾部截断容灾(自动恢复)** :
304314>
@@ -327,31 +337,46 @@ Redis 7.0 版本之后,AOF 重写机制得到了优化改进。下面这段内
327337- ** 检测阶段** :根据 AOF 文件格式逐一读取命令,判断命令参数个数、参数字符串长度等,提供错误/不完整命令的文件位置
328338- ** 修复阶段** :从错误位置截断后续文件内容(** 注意:会丢失截断点之后的所有数据** ),原文件会被备份为 ` appendonly.aof.broken`
329339
330- ** 人工修补 ** (高级用户):
340+ # ### 混合持久化模式:分段校验策略
331341
332- - 如果不想通过截断来修复 AOF 文件,可以尝试人工修补
333- - 使用文本编辑器打开 AOF 文件(纯文本格式),手动删除或修复错误命令
334- - 适用于明确知道错误位置的特定场景
342+ 在 ** 混合持久化模式** (Redis 4.0 引入)下,AOF 文件采用" 分段治理" 的校验策略:
335343
336- 在 ** 混合持久化模式** (Redis 4.0 引入)下,AOF 文件由两部分组成:
344+ ` ` `
345+ ┌─────────────────────────────────────────────────────────┐
346+ │ 混合持久化文件结构 │
347+ ├─────────────────────────────────────────────────────────┤
348+ │ RDB 快照部分(二进制) ← CRC64 校验和保护这部分 │
349+ │ ├── " REDIS" 头部 │
350+ │ ├── 数据库编号、键值对... │
351+ │ ├── EOF 标志 │
352+ │ └── CRC64 校验和(8 字节) ← 校验边界在这里 │
353+ ├─────────────────────────────────────────────────────────┤
354+ │ AOF 增量部分(文本) ← 无校验和,仅语法解析 │
355+ │ ├── * 3\r\n $3 \r\n SET\r\n ... │
356+ │ └── ... │
357+ └─────────────────────────────────────────────────────────┘
358+ ```
359+
360+ - ** RDB 快照部分** :以固定的 ` REDIS ` 字符开头,存储某一时刻的内存数据快照,并在快照数据末尾附带一个 CRC64 校验和。这个校验和** 严格卡在 RDB 数据块的末尾** ,仅保障这部分二进制快照的完整性。
361+ - ** AOF 增量部分** :紧随 RDB 快照之后,记录增量写命令。这部分** 依然没有校验和** ,采用与纯 AOF 相同的逐条语法解析验证。
362+
363+ ** 加载时的校验流程** :
337364
338- - ** RDB 快照部分** :文件以固定的 ` REDIS ` 字符开头,存储某一时刻的内存数据快照,并在快照数据末尾附带一个 CRC64 校验和(位于 RDB 数据块尾部、AOF 增量部分之前) 。
339- - ** AOF 增量部分 ** :紧随 RDB 快照部分之后,记录 RDB 快照生成后的增量写命令。这部分增量命令以 Redis 协议格式逐条记录,无整体或全局校验和 。
365+ 1 . Redis 首先校验 RDB 快照部分:计算该部分数据的 CRC64 校验和,与存储的校验和值比较。如果不匹配,Redis 拒绝启动 。
366+ 2 . RDB 部分校验通过后,逐条解析 AOF 增量命令。解析出错则停止加载后续命令(但此时 RDB 快照数据已成功加载) 。
340367
341- RDB 文件结构的核心部分如下:
368+ #### 配置项说明
342369
343- | ** 字段** | ** 解释** |
344- | ----------------- | ---------------------------------------------- |
345- | ` " REDIS" ` | 固定以该字符串开始 |
346- | ` RDB_VERSION` | RDB 文件的版本号 |
347- | ` DB_NUM` | Redis 数据库编号,指明数据需要存放到哪个数据库 |
348- | ` KEY_VALUE_PAIRS` | Redis 中具体键值对的存储 |
349- | ` EOF` | RDB 文件结束标志 |
350- | ` CHECK_SUM` | 8 字节确保 RDB 完整性的校验和 |
370+ | 配置项 | 作用域 | 说明 |
371+ | -------------------- | -------------------------------------- | -------------------------------------------------- |
372+ | ` rdbchecksum ` | RDB 文件、混合持久化的 RDB 部分 | 控制是否计算 CRC64 校验和,对纯 AOF 增量部分不生效 |
373+ | ` aof-load-truncated ` | 纯 AOF 文件、混合持久化的 AOF 增量部分 | 控制尾部截断时是否自动丢弃并继续启动 |
351374
352- Redis 启动并加载 AOF 文件时,首先会校验文件开头 RDB 快照部分的数据完整性,即计算该部分数据的 CRC64 校验和,并与紧随 RDB 数据之后、AOF 增量部分之前存储的 CRC64 校验和值进行比较。如果 CRC64 校验和不匹配,Redis 将拒绝启动并报告错误。
375+ ** 人工修补 ** (高级用户):
353376
354- RDB 部分校验通过后,Redis 随后逐条解析 AOF 部分的增量命令。如果解析过程中出现错误(如不完整的命令或格式错误),Redis 会停止继续加载后续命令,并报告错误,但此时 Redis 已经成功加载了 RDB 快照部分的数据。
377+ - 如果不想通过截断来修复 AOF 文件,可以尝试人工修补
378+ - 使用文本编辑器打开 AOF 文件(纯文本格式),手动删除或修复错误命令
379+ - 适用于明确知道错误位置的特定场景
355380
356381## 新版本优化
357382
0 commit comments