RDB 是什么
RDB 是 Redis 的二进制全量快照:把某一时刻内存里的所有键值序列化成一个文件,重启时直接加载这个文件把数据读回内存。实现上由主进程 fork 出一个子进程,子进程遍历内存数据写入临时文件,写完后再原子替换目标文件,主进程全程只负责响应请求,因此快照期间业务基本不中断(除 fork 那一刻)。文件紧凑、加载快,是 Redis 最经典的持久化与备份载体。
基本信息
| 实现方式 | fork 子进程,配合写时复制(COW)读取父进程内存快照 |
|---|---|
| 产物文件 | dbfilename 指定,默认 dump.rdb,位于 dir 目录下 |
| 触发配置 | save <秒> <变更数>,可配多组条件,命中任意一组即快照 |
| 手动命令 | BGSAVE(后台)与 SAVE(前台阻塞),LASTSAVE 查上次成功时间 |
| 代价 | fork 瞬间停顿,快照期间内存因 COW 副本上涨 |
典型使用场景
- 日常备份与冷备:文件紧凑便于按天归档,也便于一次性拷到对象存储
- 灾难恢复与快速起库:加载速度远快于重放命令,机房级故障后优先用 RDB 拉起基线
- 主从首次全量同步:从库拿到的就是主库 fork 出来的 RDB,这条链路不依赖磁盘上的旧快照
- 测试环境造数:把生产快照脱敏后导入,快速获得接近真实的数据分布
- 纯缓存业务不要求高持久化时,只用低频 RDB 做兜底,避免 AOF 的持续写盘开销
常用命令
常用命令
redis-cli CONFIG GET dir # 快照写到哪个目录
redis-cli CONFIG GET dbfilename # 文件名,默认 dump.rdb
redis-cli CONFIG GET save # 当前自动快照条件
redis-cli BGSAVE # 手动后台快照,立即返回
redis-cli LASTSAVE # 上次成功快照的 Unix 时间戳
redis-cli INFO persistence | grep -E 'rdb_last_save_time|rdb_changes_since_last_save|rdb_last_bgsave_status'关键指标读法
| 字段 | 含义 | 异常判断 |
|---|---|---|
| rdb_last_bgsave_status | 最近一次后台快照结果 | 为 err 说明磁盘或权限有问题 |
| rdb_changes_since_last_save | 距上次快照的写入次数 | 长期居高不下说明快照没成功 |
| rdb_last_save_time | 上次成功快照的时间戳 | 距今过久需核对 save 条件 |
| latest_fork_usec | 最近一次 fork 耗时(微秒) | 数十万微秒说明停顿明显 |
| rdb_bgsave_in_progress | 是否正在快照 | 长期为 1 说明快照卡住 |
不会出现半个快照的原因:子进程写的是 temp-<pid>.rdb 临时文件,全部写完后才 rename 成 dump.rdb。rename 在同一文件系统内是原子操作,所以即使写盘中途失败,磁盘上的旧快照依然可用,运维可以直接重试而不用先清理残留文件。
RDB 只保存结果,不保存过程:两次快照之间发生宕机,这段时间的写入全部丢失。丢失窗口等于快照间隔,因此生产上要么把 save 条件配得密一些,要么配合 AOF 把窗口压到秒级。
快照与重写是同一套机制:BGSAVE 与 BGREWRITEAOF 都依赖 fork,因此大实例上二者不能同时进行,Redis 会把先到的任务排队。运维上应把快照时段与重写时段错开,避免在同一个窗口里叠加两次 fork 停顿。
集群模式下每个主节点都会各自生成快照,备份不再是拷一个文件:需要在各节点上分别取 dump.rdb,并保证取文件的时间点尽量接近,否则恢复出的槽数据可能来自不同时刻。
内存水位已经接近上限时触发快照,COW 产生的额外页副本可能把内存推到超出,触发 OOM 或被淘汰策略误删业务数据。大实例应把快照安排在写入低峰,并给 used_memory_rss 留出余量。