RDB+AOF的混合持久化怎么实现的?
1 个回答
勇敢一点吧!我们不会比今年更年轻了。洪九寒自 Redis 4.0 起,开启 `AOF` 并配置 `aof-use-rdb-preamble yes` 后,**AOF 文件的“底座”用 RDB 快照写入**(称 *RDB preamble*),随后把快照之后产生的**增量写命令**继续按 AOF 追加到同一个文件尾部。重启时先“快装”RDB,再“回放”AOF 增量 → 既快又尽量少丢数据。 ## 1) 文件长什么样? ``` appendonly.aof ┌───────────────────┬──────────────────────────┐ │ RDB preamble │ AOF 增量命令(RESP 协议) │ └───────────────────┴──────────────────────────┘ 一次性快照块 快照点之后的写操作 ``` * **前半段**:完整 RDB 格式的快照(恢复速度快、体积小)。 * **后半段**:普通 AOF 命令流(保证近实时、最多丢 1 秒视 fsync 策略)。 ## 2) 它是怎么写出来的(AOF 重写时机)? AOF 会在满足阈值或手工触发 `BGREWRITEAOF` 时进行“重写”,混合持久化就是在**重写期间**完成的: 1. **父进程 fork 子进程**(Copy-on-Write); 2. **子进程**把**当前内存快照**按 **RDB 格式**写入一个临时文件(这就是 preamble); 3. 同时**父进程**仍然对外提供服务,并把期间产生的新写命令写到: * 正常 AOF 追加缓冲区(保障崩溃可恢复) * **AOF 重写缓冲区**(专门为了稍后“补尾”) 4. 子进程写完 RDB 后,**父进程**把**重写缓冲区**里的增量命令**按 AOF 语法**追加到**同一个临时文件**尾部; 5. `fsync` → **原子 `rename`** 替换旧 `appendonly.aof`。 > 好处:RDB preamble 比“把内存状态转成一条条 AOF 命令”更小更快;同时保留 AOF 的增量安全。 ## 3) 重启如何恢复? 1. 读取 `appendonly.aof` 发现**开头是 RDB 魔数** → **先按 RDB** 直接把大部分数据一把装回内存(速度快); 2. 继续从 RDB 结束处读取**AOF 命令流**,顺序回放直至文件尾; 3. 如果最后有**不完整命令**(宕机中断),按 `aof-load-truncated` 策略**截断**到最后一条完整命令。 ## 4) 关键配置与常用搭配 ```conf appendonly yes appendfsync everysec # 默认:最多丢 1 秒 aof-use-rdb-preamble yes # 打开混合持久化(Redis 4.0+) no-appendfsync-on-rewrite yes # 重写时降低 fsync 抖动 aof-rewrite-incremental-fsync yes ``` > 可与 RDB 定时快照并存;AOF 重写会优先利用 fork 子进程(与 `BGSAVE` 共用 COW 机制)。 ## 5) 为什么它更“香”? * **恢复更快**:RDB 块装载速度远快于逐条回放 AOF。 * **文件更小**:同等数据量下,RDB 表达更紧凑,重写后文件体积下降明显。 * **数据更安全**:仍保留 AOF 增量(`everysec` 通常 ≤1 秒窗口;`always` 更安全但更慢)。 * **写放大更小**:对比“纯 AOF 重写把全部状态转命令”,RDB preamble 成本更低。 ## 6) 与纯 RDB / 纯 AOF 的关系 | 方案 | 重启速度 | 数据丢失窗口 | 文件体积 | 复杂度 | | ---------------- | ----- | ----------------- | ------- | ----- | | 纯 RDB | 快 | 可能是上次快照至今 | 小 | 低 | | 纯 AOF | 慢 | 取决于 fsync(常见 ≤1s) | 大 | 中 | | **混合 (RDB+AOF)** | **快** | **≤1s(常见)** | **中/小** | **中** | ## 7) 实战小贴士 * **线上推荐**:`appendonly yes + appendfsync everysec + aof-use-rdb-preamble yes`。 * 大 key/大内存实例:混合持久化能显著缩短**重启恢复窗口**(RTO)。 * 与复制/哨兵/集群无冲突:这是**单实例持久化策略**;HA 仍靠复制 + Sentinel/Cluster。 * 容器化建议:挂载持久化卷;监控 `aof_rewrite_in_progress`、`aof_current_size`、`aof_last_bgrewrite_status`。 ### 一句话总结 > 混合持久化把 **“RDB 的快启动 + AOF 的小丢失”** 叠加起来:**AOF 文件头写 RDB 快照,尾部接增量 AOF 命令**;重启先载入 RDB,再回放增量,既缩短恢复时间又尽量保数据。编辑于 2025-10-15 15:38 •IP属地 北京举报评论收藏
公众号进入网站体验更佳

