7.2 KiB
tags, create time
| tags | create time | ||||
|---|---|---|---|---|---|
|
2026-05-15 18:12 |
RDB 持久化
概述
[!SUMMARY] RDB 是什么? RDB(Redis Database)是 Redis 最早的持久化机制,通过在特定时间点将内存中的数据集写入磁盘形成快照文件(.rdb),实现数据持久化。
核心特点
| 特性 | 说明 |
|---|---|
| ⚡ 恢复极快 | 二进制文件直接加载,避免命令回放 |
| 📦 文件紧凑 | 压缩存储,远小于等量 AOF 日志 |
| 🔧 架构简单 | 无额外复杂逻辑,适合备份和迁移 |
| ⚠️ 数据窗口丢失 | 两次快照之间的写操作不可恢复 |
何时使用
- 大数据集冷备:定期全量备份到 S3 / OSS
- 灾难恢复:配合 CI/CD 快速重建实例
- 大规模数据场景:恢复速度优先于毫秒级数据一致性
[!QUESTION] 为什么 RDB 恢复比 AOF 快? RDB 是直接加载二进制快照到内存,AOF 则需要逐条回放命令——数据量越大差距越明显。
触发机制
手动触发
# 当前线程执行,阻塞主线程 ❌
SAVE
# 主进程 fork 子进程在后台完成(推荐)
BGSAVE
# 查看上次 BGSAVE 状态
LASTSAVE
| 命令 | 行为 | 影响 |
|---|---|---|
SAVE |
同步保存,主线程阻塞 | 生产环境禁用! |
BGSAVE |
fork 子进程异步保存 | 主线程继续服务,但触发 fork 瞬间短暂停顿 |
BGREWRITEAOF |
AOF rewrite | 与 BGSAVE 可同时运行(不同子进程) |
自动触发——条件持久化
通过 redis.conf 配置:
save 900 1 # 900 秒内至少有 1 个 key 被修改 → 触发快照
save 300 10 # 300 秒内至少有 10 个 key 被修改
save 60 10000 # 60 秒内至少有 10000 个 key 被修改
[!QUESTION] 为什么要三档条件?
- 低活跃度:900s/1key 保证最终一致
- 中活跃度:300s/10key 平衡频率和数据量
- 高活跃度:60s/10000key 高频大量变更时快速落盘
# 运行时动态修改
CONFIG SET save "900 1\n300 10\n60 10000"
# 临时关闭自动快照(谨慎!)
CONFIG SET save ""
[!WARNING] CONFIG SET 不持久
CONFIG SET仅在内存中生效,重启后失效。修改redis.conf并 reload 才是持久化的方式。
其他触发场景
| 场景 | 说明 |
|---|---|
| shutdown 保存 | SHUTDOWN / SHUTDOWN NOSAVE 会在关闭前执行一次完整 RDB 保存(除非显式传 NOSAVE) |
| AOF rewrite | BGREWRITEAOF 重写 AOF 时同样会 fork 子进程生成 RDB preamble(开启混合持久化时) |
| 主从同步 | 新从节点首次全量同步时,主节点会自动触发 BGSAVE 并将快照传给从节点 |
[!TIP] 避免频繁触发 多个触发条件同时满足时,Redis 会去重,仅执行一次 BGSAVE。若已有 BGSAVE 在执行,后续的 SAVE 请求将被忽略。
RDB 文件结构
Redis 7.0+ 引入了新格式,更紧凑且支持增量复制:
flowchart TD
H1["Header"] --> H2["Magic: REDIS"]
H1 --> H3["RDB Version"]
H1 --> H4["Reserved / CRC64"]
D1["DB Number<br/>1 byte"] --> D2["Key Type<br/>1 byte"]
D2 --> D3["Encoded Key + Value"]
E1["EOF Marker"] --> E2["CRC64 Checksum<br/>8 bytes"]
H1 & H2 & H3 & H4 ==> "Dataset Section"
D1 & D2 & D3 ==> "Dataset Section"
D3 -.-> "... N keys ..."
E1 & E2 ==> "Footer"
Fork 过程详解
sequenceDiagram
participant Server as Redis Server
participant Parent as 主进程
child ForkGroup as Forked Child
participant Child as 写时复制子进程
participant Disk as 磁盘 (.rdb)
end
Server->>Parent: BGSAVE 指令
Parent->>Server: OK(立即返回)
Parent->>Child: fork() 创建子进程
Note over Child: 子进程独享父进程<br/>内存副本(写时复制 COW)
Child->>Disk: 遍历所有 key → 序列化
Note over Child: 主进程仍可读写<br/>COW 机制按需拷贝脏页
Child->>Parent: 生成临时 .rdb.tmp
Parent->>Disk: RENAME 原子替换
Parent->>Server: BGSAVE 完成通知
[!WARNING] COW 内存消耗 fork 后主进程若持续写入大值,会导致 COW 副本膨胀。例如你有一个 1GB 的值被频繁修改,fork 后每次写都可能多拷贝一页(4KB)。高峰期建议关闭自动 RDB,仅依赖 AOF。
TTL / 过期键处理
[!QUESTION] RDB 快照会保存已过期的 key 吗? 不会。 Redis 在 fork 子进程前会先执行一次主动过期扫描,清理掉所有已超时的 key。
具体流程:
BGSAVE触发时,主线程先将当前所有已过期 key 从内存中删除- 子进程 fork 完成后遍历剩余 key → 序列化到 .rdb 文件
- 因此:RDB 文件中不会出现已过期键
flowchart LR
A["BGSAVE 触发"] --> B["主线程: 主动过期<br/>清理超时 Key"]
B --> C["Fork 子进程"]
C --> D["子进程: 遍历剩余数据<br/>序列化到 .rdb"]
D --> E[".rdb 无过期键"]
style E fill:"#c4e8b0"
[!NOTE] 过期策略差异 虽然 RDB 不保存过期键,但 AOF 可能包含过期命令(如之前的 SET k v EX 100)。AOF 重写时会主动过滤过期键,恢复时也只会加载有效数据。两者优先保证启动时的数据一致性。
恢复流程
# 1. 停止 Redis
redis-cli SHUTDOWN NOSAVE
# 2. 把 .rdb 放到 redis_dir(由 dir 配置决定)
cp dump.rdb /var/lib/redis/
# 3. 启动 Redis
redis-server --daemonize yes
# 4. 验证数据恢复
redis-cli DBSIZE
redis-cli KEYS "*"
RDB vs AOF 对比
| 维度 | RDB | AOF |
|---|---|---|
| 数据安全性 | 两次快照间数据丢失 | 每秒/每次可配置,接近零丢失 |
| 恢复速度 | ⚡ 极快(直接加载二进制文件) | 🐢 较慢(需要回放日志) |
| 文件大小 | ✅ 小(紧凑压缩) | ❌ 大(文本命令日志) |
| CPU 开销 | 低(偶尔 fork) | 高(持续追加写入) |
| 适用场景 | 备份、灾难恢复、大数据集冷备 | 对可用性要求高的在线服务 |
| 重启耗时 | 秒级 | 取决于日志长度(可 pre-fork) |
Redis 7 混合持久化
结合 RDB + AOF 的优点:
aof-use-rdb-preamble yes
开启后,AOF rewrite 不再只追加命令日志,而是先写入一份 RDB 快照,再追加后续命令:
flowchart LR
T1["传统 AOF 重建<br/>逐条命令回放"] -->|"O(N) 慢"| R1["重建耗时: 长"]
H1["RDB 二进制快照<br/>全量快速还原"] -->|"秒级加载"| R2["重建耗时: 短"]
H2["AOF 增量日志<br/>仅保留变更后操作"] -->|"精确到毫秒"| R2
style R1 fill:"#f9d0c4"
style R2 fill:"#c4e8b0"
[!TIP] 混合持久化几乎是无脑开启的配置——启动快 + 不丢数据。
运维要点
# 监控 RDB 相关指标
INFO persistence
# rdb_last_bgsave_status: OK
# rdb_last_save_time: 1715000000 ← 最后成功时间戳
# 检查文件大小
ls -lh /var/lib/redis/dump.rdb
# 压缩备份(已内置 LZ4 压缩,通常不需要额外压缩)
tar czf redis-backup.tar.gz dump.rdb
关联笔记
- hhs/Redis/05-AOF持久化 — AOF 持久化机制
- hhs/Redis/06-主从与哨兵 — Sentinel 故障转移流程
- hhs/Redis/09-运维调优 — 备份策略与大 Key 治理