混合持久化文件结构为前半部分标准RDB二进制数据(以“REDIS”魔数开头)、后半部分纯文本AOF命令流,两者通过RDB自身长度信息严格分界,中间无显式分隔符。

混合持久化文件的结构本质
Redis 4.0+ 的混合持久化(aof-use-rdb-preamble yes)不是简单拼接,而是严格分段:前半部分是标准 RDB 格式二进制数据,后半部分是纯文本 AOF 命令流。两者之间没有分隔符,但有明确的协议边界——RDB 数据以固定魔数 REDIS 开头,AOF 部分以 *[数字](RESP 协议数组开头)紧随其后。关键在于:RDB 段本身自带长度信息(通过 RDB 版本号、EOF 标记和校验和可定位结束位置),之后所有字节都属于 AOF。
用 hexdump + grep 快速定位分界点
直接读取混合 AOF 文件(默认 appendonly.aof)时,别用文本编辑器硬打开。执行:
hexdump -C appendonly.aof | head -n 50
你会看到开头是:
00000000 52 45 44 49 53 30 30 31 31 0a 03 00 00 00 00 00 |REDIS0011.......|
这就是 RDB 头。继续向下找第一个 2a(即 ASCII *)出现的位置:
grep -ab "2a" <p>更实用的是用 <code>redis-check-aof --fix</code> 验证时它会自动报告 “RDB preamble ends at offset XXX”,这个 <code>XXX</code> 就是分界点。</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill11046" title="Sentinal Redis"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="Sentinal Redis" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill11046" title="Sentinal Redis" class="overflowclass">Sentinal Redis</a> <p class="overflowclass">监控Redis服务器健康状况、内存、性能及BullMQ队列。检查队列深度、失败任务,分析慢查询并诊断问题。</p> </div> <a rel="nofollow" href="/xiazai/skill11046" title="Sentinal Redis" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div><h3>用 <a style="color:#f60; text-decoration:underline;" title="redis" href="https://m.php.cn/zt/15737.html" target="_blank">redis</a>-cli --pipe 检查 AOF 部分是否合法</h3><p>RDB 段不可执行,AOF 段必须能被 Redis 重放。快速验证后半部分是否为有效 AOF:</p>
- 先用
redis-cli --pipe 测试小片段(如从 offset 1MB 开始取 1KB) - 若报错
Protocol error: expected '$', got '*',说明该位置不是 AOF 起始——很可能还在 RDB 段内 - 真正 AOF 起始处第一条命令通常是
*3\r\n$3\r\nSET\r\n$2\r\nk1\r\n$2\r\nv1\r\n这类完整 RESP 结构
注意:redis-check-aof --fix 会尝试解析整个文件并提示首个非法命令位置,那个位置之前就是 RDB 段终点。
容易忽略的坑:RDB 段末尾可能含空字节或校验残留
RDB 段结尾不一定是干净的 EOF 标记。某些版本在写入混合文件时会在 RDB 末尾补零(00)对齐,或残留 CRC64 校验字段。这些字节仍属 RDB 逻辑范围,不能当成 AOF 解析。最稳妥的方式是依赖 redis-check-aof 输出的 offset,而不是靠肉眼找 *——因为 AOF 中的 key 名或 value 也可能含 * 字符(虽然罕见)。混合文件的“分界”是协议定义的,不是字符串匹配出来的。










