bigywater.tech
Redis · 61

RDB 与 AOF 混合持久化

「RDB 和 AOF 混合持久化」到底混合了什么?答案是:AOF 重写产出的 base 文件是 RDB 格式,之后追加的增量仍是命令文本。这篇用同一份 50 万个 key 的数据集,分别用 RDB、开 preamble 的 AOF、关 preamble 的 AOF 持久化,比较文件格式、大小和重启加载时间。

39.4 vs 50.9 MB
AOF base:RDB 格式(preamble yes)vs 命令文本(preamble no)
0.21 vs 0.37 s
重启加载耗时:preamble yes vs no
700000
混合持久化重启后 DBSIZE(50 万 base + 20 万 incr)

三种格式并排

500000 个 key,每种配置一个新实例
实测 · 本机执行输出
配置                         文件                              大小(MB) 文件头                            重启加载耗时
AOF + RDB preamble(默认)     appendonly.aof.2.base.rdb         39.4 b'REDIS0015\xfa\tredis-ver\x068.10.'     0.26 s   (日志: DB loaded from append only file: 0.215 seconds)
AOF,无 preamble(纯命令)        appendonly.aof.2.base.aof         50.9 b'*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n*3\r'     0.40 s   (日志: DB loaded from append only file: 0.374 seconds)
只有 RDB                     dump.rdb                          39.4 b'REDIS0015\xfa\tredis-ver\x068.10.'     0.24 s   (日志: DB loaded from disk: 0.222 seconds)

文件头一眼就能分清:preamble 为 yes 时 AOF 的 base 文件以 REDIS0015 开头,是 RDB;为 no 时是 *2\r\n$6\r\nSELECT 开头的 RESP 命令文本。大小:RDB 格式 39.4 MB(与纯 RDB 的 dump.rdb 一样大),命令文本 50.9 MB,大约多 29%。加载耗时(日志里的秒数):0.215 s / 0.374 s / 0.222 s(AOF+preamble / AOF 纯命令 / RDB)。每种配置只做了一次重启测量,毫秒级的差别不要当结论;命令文本更慢这个方向是清楚的(约 74%)。

这里的 value 是随机十六进制字符串,压缩率低,所以 RDB 只比命令文本小两成多;value 像上一个实验(第 54 篇)里那样重复度高时,RDB 会小得多。

「混合」:RDB base + 增量命令

实测 · 本机执行输出
  39388988  appendonly.aof.2.base.rdb
  11188913  appendonly.aof.2.incr.aof
       107  appendonly.aof.manifest
incr 文件开头: b'*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n*3\r\n$3\r\nSET\r\n$5\r\nnew:0\r\n$20\r\nvvvvvvvv'
重启后 DBSIZE = 700000(应为 700000);加载耗时约 0.40 s
  Configuration loaded
  Successfully created the temporary AOF base file temp-rewriteaof-bg-35706.aof
  Fork CoW for AOF rewrite: current 0 MB, peak 0 MB, average 0 MB
  Background AOF rewrite terminated with success
  Successfully renamed the temporary AOF base file temp-rewriteaof-bg-35706.aof into appendonly.aof.2.base.rdb
  Background AOF rewrite finished successfully
  Calling fsync() on the AOF file.
  Configuration loaded
  Reading RDB base file on AOF loading...
  RDB is base AOF
  Done loading RDB, keys loaded: 500000, keys expired: 0.
  DB loaded from base file appendonly.aof.2.base.rdb: 0.202 seconds
  DB loaded from incr file appendonly.aof.2.incr.aof: 0.174 seconds
  DB loaded from append only file: 0.377 seconds
  Opening AOF incr file appendonly.aof.2.incr.aof on server start

重写之后再写 20 万个 key,incr 文件是 11.2 MB 的命令文本(开头能看到 SELECT 0 和 SET new:0 …)。重启日志分两段:DB loaded from base file … 0.202 seconds,然后 DB loaded from incr file … 0.174 seconds,合计 0.377 秒,DBSIZE = 700000。增量越大,回放越久——这也是要定期重写的原因。

分步演示:三种格式

混合持久化
本步的数据

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。三种配置的对比来自同一份数据(random.Random(1) 生成);每种配置只测一次重启
    • 没有验证:更大的数据集下的差别、value 高度可压缩时的大小差异、AOF 混合持久化在 fork 时对主进程的影响(第 66 篇)、关闭 aof-use-rdb-preamble 后重写产出 base.aof 的其它细节
    京ICP备2026067502号-1京公网安备11010502063487号