Skip to content

03.1 - RDB 快照机制

定位: Redis 的全量数据快照——用 fork + 写时复制在保证性能的前提下做数据备份 面试高频度: ⭐⭐⭐⭐ 考查方式: RDB 触发方式、写时复制原理、fork 对性能的影响、RDB 的优劣


一、这是什么?为什么需要它?

是什么

RDB(Redis Database)是 Redis 的全量快照持久化机制,将某个时刻的内存数据以二进制格式写入磁盘文件(dump.rdb)。

为什么需要 RDB?

问题:如果 Redis 只存内存,宕机后数据全丢

方案 1:RDB 快照
  ✓ 二进制格式,恢复极快(加载 + 反序列化)
  ✓ 文件小(压缩)
  ✓ 适合做备份、灾难恢复
  ✗ 可能丢失最后一次快照之后的数据

方案 2:AOF 日志
  ✓ 最少丢数据(1 秒内的数据)
  ✗ 恢复慢(要重放所有操作)
  ✗ 文件大(文本日志)

两者是互补关系:
  RDB 做"地基"——快速恢复大部分数据
  AOF 做"补丁"——恢复最后一次 RDB 后的少量修改

二、原理拆解

2.1 触发方式

2.2 写时复制(Copy-On-Write)原理

2.3 fork 的性能影响

fork 本身的开销:
  复制页表(页表大小 ≈ 物理内存 / 页大小 × 8字节)
  
  8GB 内存 Redis:页表 ≈ 8GB/4KB × 8B = 16MB(复制量)
  32GB 内存 Redis:页表 ≈ 32GB/4KB × 8B = 64MB(复制量)

  fork 时间 ≈ 内存量 × 页表复制速度
  实测:32GB 内存约 300-500ms(这个时间内主进程阻塞!)

COW 的内存翻倍风险:
  bgsave 期间父进程大量写入
  → COW 复制大量页面
  → 实际内存 ≈ 数据集 + COW 复制的页面数

  监控指标:INFO persistence 中的
  rdb_last_cow_size(上次 bgsave 的 COW 内存量)

2.4 RDB 文件结构


三、图解全景


四、实战验证

4.1 手动触发 RDB

bash
redis-cli

# 1. BGSAVE
127.0.0.1:6379> BGSAVE
Background saving started

# 2. 查看持久化状态
127.0.0.1:6379> INFO persistence
# Persistence
rdb_last_save_time:1678901234
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:2
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:52387840  # COW 复制了约 50MB

# 3. 确认 RDB 文件
$ ls -lh /var/lib/redis/dump.rdb
-rw-r--r-- 1 redis redis 1.2G Mar 15 10:00 dump.rdb

4.2 观察 fork 行为

bash
# 查看进程 fork 时间
redis-cli INFO latest_fork_usec
# 136789  # fork 花了 136ms

# 监控内存翻倍(大内存服务器注意)
# 在 bgsave 期间观察
redis-cli INFO memory | grep used_memory_human
# used_memory_human:2.8G    ← 正常情况下
# bgsave 期间:
# used_memory_human:5.1G    ← COW 造成内存翻倍!

4.3 用 RDB 做备份恢复

bash
# 1. 手动触发 RDB
redis-cli BGSAVE

# 2. 复制 RDB 做异地备份
cp /var/lib/redis/dump.rdb /backup/redis/dump.$(date +%Y%m%d).rdb

# 3. 模拟恢复(清空当前数据)
redis-cli FLUSHALL

# 4. 关闭 Redis,将备份文件放回,重启
sudo systemctl stop redis
cp /backup/redis/dump.20240712.rdb /var/lib/redis/dump.rdb
sudo systemctl start redis

# 5. 验证数据
redis-cli DBSIZE  # 数据恢复

五、面试视角

追问答案要点
RDB 的 save 和 bgsave 区别?save 阻塞主进程(不推荐);bgsave fork 子进程处理(推荐)
写时复制(COW)如何工作?fork 不复制物理内存,父进程写入某页时先复制再写,子进程读原页
RDB 的触发条件?自动:配置 save 规则;手动:BGSAVE/SAVE;特殊:shutdown、主从全量复制
bgsave 对性能的影响?fork 阻塞主进程(毫秒级),COW 可能导致内存翻倍,磁盘 I/O 写入带宽
RDB 的缺点?数据丢失窗口(上次快照后的数据)、fork 大内存场景的阻塞风险、COW 翻倍风险
在线大内存实例怎么做 RDB?评估内存(留有足够 COW 余量)、配置系统 vm.overcommit_memory=1、从节点做备份
RDB 文件的校验?文件末尾有 8 字节校验和,加载时自动校验

📚 相关链接

  • **AOF 日志机制** — RDB 的互补方案
  • **混合持久化** — 生产最佳实践
  • ← 返回 **持久化索引**

Knowledge4J — Java 知识库