vault backup: 2026-05-21 23:50:11

This commit is contained in:
hhs
2026-05-21 23:50:11 +08:00
parent c3779073e9
commit b2b947f9f4
3 changed files with 363 additions and 212 deletions
+62 -1
View File
@@ -107,6 +107,34 @@ flowchart TD
E1 & E2 ==> "Footer"
```
### 各段含义
| 段落 | 内容 | 说明 |
|------|------|------|
| **Header** | Magic + Version + 校验 | `REDIS` 魔数标识文件类型;版本号用于兼容性判断;CRC64 用于完整性校验 |
| **DB Selector** | 数据库编号 | 默认 16 个 DB(0-15),只序列化非空 DB |
| **Key-Value Pairs** | 类型 + 编码 + 数据 | 每个 key 携带类型标记(String/List/Hash/ZSet…),底层编码直接序列化,因此文件极紧凑 |
| **EOF** | `0xFF` 终止符 | 标识数据段结束 |
| **Footer** | CRC64 校验和 | 8 字节,启动加载时校验文件完整性 |
> [!QUESTION] 为什么 RDB 文件比 AOF 小很多?
> 因为 RDB 直接序列化底层数据结构(如 ziplist、intset),而非记录产生这些数据的命令字符串。一个 Hash 用 ziplist 存储可能只有几十字节,但生成它的 HSET 命令可能有数百字节。
## 关键配置参数
```conf
# ---- RDB 核心参数 ----
dbfilename dump.rdb # 快照文件名
dir /var/lib/redis # 工作目录,RDB/AOF 文件存放位置
rdbcompression yes # 是否使用 LZF 压缩字符串(推荐开启,CPU vs 磁盘权衡)
rdbchecksum yes # 是否在文件末尾写入 CRC64 校验(推荐开启)
rdb-save-incremental-fsync yes # 写入磁盘时增量 fsync,避免一次性大量 I/O 阻塞
rdb-del-sync-files no # 无盘复制时,是否删除用于同步的临时 RDB(Redis 7+)
```
> [!TIP] rdbcompression 的取舍
> 开启压缩可以显著减少磁盘占用(通常压缩 40%-60%),代价是写入时多消耗一点 CPU。对于绝大多数场景,**保持 yes** 是最优解。只有在 CPU 极度敏感、磁盘充裕的特殊场景下才考虑关闭。
## Fork 过程详解
```mermaid
@@ -132,6 +160,26 @@ sequenceDiagram
> [!WARNING] COW 内存消耗
> fork 后主进程若持续写入大值,会导致 COW 副本膨胀。例如你有一个 1GB 的值被频繁修改,fork 后每次写都可能多拷贝一页(4KB)。高峰期建议关闭自动 RDB,仅依赖 AOF。
### 深入理解 COW(Copy-On-Write)
fork 后父子进程共享同一份物理内存页(只读),只有当某一方**写入**时,内核才会真正复制该页——这就是"写时复制"。
```mermaid
flowchart TD
F["Fork 完成"] --> S["父子进程共享<br/>所有物理内存页"]
S --> W{"主进程收到<br/>写请求?"}
W -->|"否"| R["子进程继续读取<br/>(零拷贝, 极快)"]
W -->|"是"| C["内核复制该内存页<br/>(Copy-On-Write)"]
C --> N["主进程写入副本<br/>子进程仍读原页"]
R & N --> D["子进程完成序列化"]
D --> DONE["RDB 文件生成"]
```
> [!QUESTION] 为什么 Redis 占用内存会翻倍?
> 这是面试高频题。答案是:**不会翻倍,但最坏情况接近翻倍。** fork 本身不复制内存,只有**主进程实际写入的页面**才会被 COW。如果 BGSAVE 期间主进程几乎不写入,额外内存开销几乎为零。但若全量写入,就会逐步逼近 2 倍。
>
> **运维经验**:保持系统 `vm.overcommit_memory=1`(Linux 默认),否则 fork 可能因内核认为内存不足而失败。
### TTL / 过期键处理
> [!QUESTION] RDB 快照会保存已过期的 key 吗?
@@ -206,6 +254,19 @@ flowchart LR
> [!TIP] 混合持久化几乎是无脑开启的配置——启动快 + 不丢数据。
## 最佳实践
> [!SUMMARY] 核心原则:RDB 是备份手段,不是实时数据保障
1. **不要只依赖 RDB**:生产环境推荐 `AOF + RDB` 混合持久化,AOF 保证数据安全性,RDB 保证快速恢复
2. **合理设置触发频率**:默认三档(900s/300s/60s)适合大部分场景;写入密集型业务可适当提高频率,但注意 fork 开销
3. **监控 fork 耗时**:`INFO persistence` 中的 `rdb_last_bgsave_time_sec`,超过 1s 就需要关注
4. **备份策略**:定期将 `.rdb` 文件拷贝到异地存储(S3/OSS),建议保留多个历史版本
5. **磁盘选择**:RDB 文件写入对磁盘 I/O 有要求,建议使用 SSD 并配合 `rdb-save-incremental-fsync`
> [!WARNING] 大 Key 是 RDB 的天敌
> 一个 100MB 的 String key,序列化时会导致子进程写入耗时剧增,同时 COW 也可能产生大量页面复制。发现大 Key 后应优先拆分。
## 运维要点
```bash
@@ -225,4 +286,4 @@ tar czf redis-backup.tar.gz dump.rdb
- [[hhs/Redis/05-AOF持久化]] — AOF 持久化机制
- [[hhs/Redis/06-主从与哨兵]] — Sentinel 故障转移流程
- [[hhs/Redis/09-运维调优]] — 备份策略与大 Key 治理
- [[hhs/Redis/11-运维与性能调优]] — 备份策略与大 Key 治理