2. RDB原理:RDB快照机制、触发方式(save/bgsave)、写时复制(COW)技术
2.1 RDB快照机制概述
RDB(Redis Database)持久化通过生成某一时刻的内存快照(Snapshot)来实现数据持久化。快照是一个经过压缩的二进制文件,默认名为 dump.rdb,存储在 Redis 工作目录中。RDB 的核心设计思想是“全量备份 + 定时触发”,适合用于灾难恢复、冷备份以及大规模数据迁移场景。
适用场景:RDB 文件体积小、加载速度快,非常适合每小时或每天执行一次全量备份,用于主从复制的初始全量同步也是 RDB 的经典用途。
2.2 RDB触发方式:save 与 bgsave
Redis 提供两种触发 RDB 快照的方式:save(同步阻塞)和 bgsave(异步后台)。两者的核心区别在于是否阻塞主进程处理客户端请求。
| 触发方式 | 执行过程 | 阻塞主进程 | 适用场景 |
|---|---|---|---|
| save | 由主进程直接执行快照生成,期间不处理任何命令 | 是(完全阻塞) | 仅限停机维护、手动备份等非服务时段 |
| bgsave | 主进程 fork 子进程,由子进程异步生成快照 | 否(仅 fork 时短暂阻塞) | 生产环境默认使用,不影响正常读写 |
2.2.1 手动触发命令
# 同步阻塞式快照(不推荐生产使用)
127.0.0.1:6379> save
OK
# 异步后台快照(生产推荐)
127.0.0.1:6379> bgsave
Background saving started
2.2.2 自动触发配置
通过 redis.conf 中的 save 指令配置自动触发条件,格式为 save <seconds> <changes>,表示在 N 秒内至少有 M 次写操作时自动执行 bgsave。
# 默认配置示例
save 900 1 # 900秒(15分钟)内至少有1次写操作
save 300 10 # 300秒(5分钟)内至少有10次写操作
save 60 10000 # 60秒(1分钟)内至少有10000次写操作
# 禁用自动RDB(仅使用AOF时)
save ""
配置建议:生产环境通常保留默认三条规则,或根据业务写入频率调整。写入频繁的业务可缩短时间窗口或降低变更次数阈值,避免两次快照间隔过长导致数据丢失风险增大。
2.3 写时复制(COW)技术
写时复制(Copy-On-Write)是 bgsave 能够实现非阻塞持久化的底层支撑技术。当执行 bgsave 时,Redis 主进程通过 fork() 系统调用创建一个子进程,子进程与主进程共享同一份内存页。只有在主进程或子进程需要修改某个内存页时,才会真正复制该页,从而大幅降低内存开销和 fork 延迟。
注意:COW 虽然高效,但在写入量极大的场景下,主进程每修改一个内存页都会触发页复制,可能导致实际内存占用瞬间翻倍。建议为 Redis 预留足够的内存余量(通常为实际数据量的 1.5~2 倍)。
2.4 RDB 执行流程详解
一次完整的 bgsave 执行过程包含以下关键步骤:
- 触发检查:Redis 检查当前是否已有子进程在执行持久化(RDB 或 AOF 重写),若有则直接返回,避免并发冲突。
- fork 子进程:主进程调用
fork()创建子进程,此时主进程短暂阻塞(通常微秒级到毫秒级,取决于内存大小)。 - 子进程写 RDB:子进程利用 COW 机制读取共享内存,将数据写入临时 RDB 文件(如
temp-xxx.rdb)。 - 原子替换:子进程写完 RDB 文件后,通过
rename(2)系统调用将临时文件原子替换为目标文件dump.rdb。 - 通知主进程:子进程退出并向主进程发送信号,主进程更新持久化状态统计信息。
关键指标:可通过
INFO Persistence 命令查看最近一次 RDB 快照的状态,重点关注 rdb_last_save_time(上次成功时间)和 rdb_last_bgsave_status(上次状态)。
2.5 RDB 的优缺点对比
| 维度 | 优势 | 劣势 |
|---|---|---|
| 文件体积 | 二进制压缩,体积小,适合备份传输 | — |
| 加载速度 | 直接还原内存结构,比 AOF 重放快数倍 | — |
| 数据完整性 | — | 两次快照间隔内的数据可能丢失(取决于 save 配置) |
| 实时性 | — | 无法做到秒级持久化,频繁 fork 对 CPU 和内存有压力 |
| 内存开销 | COW 技术减少内存复制 | 写入量大时 COW 可能导致内存翻倍 |
工程建议:RDB 适合作为“兜底”持久化方案,与 AOF 配合使用(混合持久化)可兼顾数据安全与恢复速度。在纯缓存场景下,甚至可以关闭所有持久化以追求极致性能。