18. 持久化 RDB
本教程共 40 篇 · 第 18 篇 · 更新于 2026-08-02
18. 持久化 RDB
Redis 是内存数据库,所有数据默认都在内存里。一旦进程退出或服务器断电,内存中的数据就会消失。为了让数据“落盘可恢复”,Redis 提供了两种持久化方案,第一种就是 RDB(Redis Database)——它把某个时间点的全量数据拍成一张“快照”存到磁盘。
RDB 是 Redis 最早、也最经典的持久化方式,理解它之后,再看 AOF 与混合持久化就会非常轻松。
本节目标
- 理解 RDB 的本质:某一时刻的内存快照(snapshot)。
- 区分
SAVE(同步阻塞)与BGSAVE(后台异步)两种触发方式。 - 掌握
redis.conf中save触发条件与dir/dbfilename等配置。 - 学会通过复制
dump.rdb完成数据恢复。 - 清楚 RDB 的优缺点,避免把它当成“实时备份”。
RDB 是什么
RDB 持久化的结果是单个二进制文件(默认叫 dump.rdb)。它通过 fork 出一个子进程,把父进程当前内存里的数据序列化后写入临时文件,写完后用临时文件原子替换旧的 dump.rdb。因此磁盘上永远存在一个完整可用的快照,你可以随时拷走它做备份。
因为 RDB 是“全量快照”,恢复时只要把这个文件放回 Redis 的数据目录再启动即可,速度非常快。
SAVE 与 BGSAVE
手动触发快照有两条命令:
SAVE 是同步的——它在主进程里直接写盘,期间服务器完全阻塞,不再响应任何客户端请求。数据量大时,SAVE 可能让 Redis 卡住数秒甚至更久,生产环境应尽量避免。
127.0.0.1:6379> SAVE
OK
BGSAVE(Background SAVE)则是异步的——Redis 会 fork 一个子进程去负责写盘,父进程继续正常服务客户端。这也是 Redis 内部定时触发快照所采用的方式。
127.0.0.1:6379> BGSAVE
Background saving started
可以用 LASTSAVE 拿到最近一次成功落盘的时间戳,再用 INFO persistence 检查后台保存是否成功:
127.0.0.1:6379> LASTSAVE
(integer) 1722345600
127.0.0.1:6379> INFO persistence
# Persistence
rdb_bgsave_in_progress:0
rdb_last_bgsave_status:ok
rdb_last_save_time:1722345600
rdb_last_bgsave_time_sec:1
提示:
BGSAVE的“不阻塞”是有前提的:fork 子进程瞬间需要把整个内存页表复制一份。当内存很大(几十 GB)或写操作密集时,fork 本身和后续的写时复制(Copy-On-Write)可能带来可感知的延迟毛刺。这是使用 RDB 时性能调优要留意的点。
自动触发:redis.conf 中的 save
更常见的是让 Redis 按条件自动做快照。redis.conf 里用 save 配置项定义“在多少秒内至少发生多少次写,就触发一次 BGSAVE”:
# Redis 8.x 默认触发条件
save 3600 1
save 300 100
save 60 10000
含义是:3600 秒内至少有 1 次写、或 300 秒内至少有 100 次写、或 60 秒内至少有 10000 次写,任一条件满足就后台保存。你可以根据自己的写入频率增删 save 行;若想完全关闭自动 RDB,把全部 save 行删掉(或写成 save "")即可。
127.0.0.1:6379> CONFIG GET save
1) "save"
2) "3600 1 300 100 60 10000"
其他相关配置:
dir:RDB 文件存放目录(恢复时要把dump.rdb放到这里)。dbfilename:快照文件名,默认dump.rdb。stop-writes-on-bgsave-error yes:若后台保存失败(如磁盘满),主进程停止接受写命令,防止数据只活在内存里。rdbcompression yes:对字符串对象做 LZF 压缩,省空间。rdbchecksum yes:文件末尾加 CRC64 校验,加载时检测损坏。
查看文件目录:
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"
用 RDB 恢复数据
RDB 恢复是无感的:只要把备份好的 dump.rdb 放到 dir 指定的目录,再启动 Redis,服务器启动时就会自动加载它。操作步骤:
- 找到目标目录:
CONFIG GET dir。 - 把备份的
dump.rdb覆盖到该目录。 - 启动(或重启)Redis 服务。
需要提醒:如果同时开启了 AOF,Redis 启动时会优先加载 AOF(AOF 的完整性通常更高),此时单独的 RDB 不会被用作恢复来源——这一点在第 20 章混合持久化里会详细说明。
RDB 的优缺点
优点
- 快照是单一紧凑的二进制文件,非常适合做定时备份、灾难恢复和迁移。
- 恢复速度远快于 AOF,因为不需要重放命令,直接反序列化即可。
BGSAVE由子进程完成,对正常服务影响小(fork 毛刺除外)。
缺点
- 它是“时间点”快照,两次快照之间的写入会丢失。即使设成 60 秒一存,崩溃时仍可能丢掉最近一分钟的数据。
- 数据量巨大时,fork 子进程的成本会变高,可能短暂影响响应。
- 老版本 RDB 格式与新版本不完全向下兼容(升级通常没问题,降级可能失败)。
因此,RDB 适合“能容忍分钟级数据丢失、更看重恢复速度”的场景,例如纯缓存、或作为 AOF 的兜底快照。
小结
- RDB = 全量内存快照,默认文件
dump.rdb,由 fork 子进程异步写出。 - 手动用
SAVE(阻塞)或BGSAVE(后台);自动靠save配置按写频率触发。 - 恢复只需把
dump.rdb放回dir目录再启动;若启用 AOF 则以 AOF 为准。 - 优势是恢复快、文件紧凑;短板是两次快照间的数据会丢,不适合做“零丢失”方案。
常见误区
- 误区一:以为
BGSAVE完全无阻塞。 它确实不阻塞正常命令处理,但 fork 子进程那一刻要复制整个内存页表。当内存达几十 GB、且写操作密集触发大量写时复制(Copy-On-Write)时,仍可能产生可感知的延迟毛刺。对延迟极度敏感的服务,应监控 fork 耗时(INFO里的latest_fork_usec)。 - 误区二:把 RDB 当成“实时备份”。 RDB 是时间点快照,两次快照之间的所有写入在崩溃时会丢失。它适合做“能容忍分钟级丢失”的缓存或备份,而不是零丢失方案。
- 误区三:运行中手动删/换
dump.rdb能立即生效。 RDB 只在启动时加载一次,运行中修改磁盘文件对运行中的实例没有任何影响;而且误删快照文件,下次重启就无据可恢复了。 - 误区四:跨版本随意互用 RDB。 低版本 RDB 通常能被高版本加载,但高版本若写入了新类型(如 8.x 的向量集、JSON),其 RDB 无法被低版本识别,降级不保证成功。迁移大版本时建议用
redis-cli --rdb或主从全量同步而非直接拷贝文件。
提示:本教程统一基于 Redis 8.x(最新稳定版)行文。补充说明:官方 redis.io 下载页另标 8.8 为 “Latest stable”,而 GitHub 上的最新发布 tag 为 8.10.0,二者同属 8.x 大版本,对 RDB 命令与配置项的讲述没有影响。