Redis 的 RDB 持久化

Redis 的 RDB 持久化 ,本质是通过生成内存数据的快照文件(.rdb来保存数据,Redis 重启时加载该文件即可恢复数据。RDB 是 Redis 默认的持久化方式,支持手动触发自动触发两种模式,下面从核心机制、配置、操作步骤、恢复流程、优缺点等方面,详细说明如何使用 RDB 持久化。

一、RDB 持久化的核心原理

  1. 快照生成逻辑当触发 RDB 持久化时,Redis 会执行以下步骤:

    • Redis 主进程 fork 一个子进程(父子进程共享内存数据);
    • 子进程遍历内存中的数据,将其写入到一个临时的 RDB 文件中;
    • 子进程写入完成后,用临时文件替换旧的 RDB 文件(原子操作,保证文件完整性);
    • 子进程退出,主进程继续处理客户端请求。 关键:fork 操作会产生 ** 写时复制(Copy-On-Write)** 机制 ------ 父子进程共享内存页,只有当主进程修改数据时,才会复制对应内存页,避免占用双倍内存。
  2. RDB 文件特性

    • 文件名默认是 dump.rdb,是二进制压缩文件,体积小,便于传输和备份;
    • 一个 RDB 文件包含某一时刻 Redis 的全量数据快照,恢复时直接加载到内存,速度远快于 AOF 持久化。

二、RDB 持久化的触发方式

RDB 有两种触发方式:手动触发 (按需执行)和自动触发(配置规则自动执行)。

1. 手动触发(常用)

手动触发有两个命令:SAVEBGSAVE,生产环境优先使用 BGSAVE

命令 执行逻辑 优点 缺点 适用场景
SAVE 主进程直接生成 RDB 文件,阻塞所有客户端请求 无需 fork 子进程,无内存开销 阻塞 Redis,期间无法处理命令 测试环境、数据量极小的场景
BGSAVE 主进程 fork 子进程生成 RDB 文件,主进程不阻塞 不影响 Redis 正常服务 fork 子进程会消耗内存(大内存实例 fork 较慢) 生产环境、日常备份
实操示例
bash 复制代码
# 1. 手动执行 BGSAVE(推荐)
127.0.0.1:6379> BGSAVE
Background saving started  # 提示:后台保存已启动

# 2. 查看 BGSAVE 执行状态(通过 INFO 命令)
127.0.0.1:6379> INFO persistence
# Persistence
rdb_changes_since_last_save: 0  # 上次保存后数据变化量
rdb_bgsave_in_progress: 0       # 0=未执行,1=正在执行
rdb_last_save_time: 1719234567  # 上次保存的时间戳
rdb_last_bgsave_status: ok      # 上次保存状态:ok=成功,err=失败
2. 自动触发(配置规则)

通过修改 redis.conf 配置文件,设置数据变化触发条件 ,Redis 会在满足条件时自动执行 BGSAVE

核心配置项是 save <seconds> <changes>,格式为:save 时间窗口(秒) 数据变化次数,可以配置多个条件(满足任意一个即触发)。

配置示例(redis.conf)
复制代码
# 900秒内至少1个键被修改 → 触发 BGSAVE
save 900 1
# 300秒内至少10个键被修改 → 触发 BGSAVE
save 300 10
# 60秒内至少10000个键被修改 → 触发 BGSAVE
save 60 10000

# 禁用自动触发 RDB(注释所有 save 配置,或添加下面一行)
# save ""
其他自动触发场景
  • 执行 FLUSHALL 命令 :会清空所有数据,并生成一个空的 dump.rdb 文件(生产环境慎用)。
  • 主从复制时 :主节点首次向从节点同步数据时,会自动执行 BGSAVE 生成 RDB 文件,发送给从节点。

三、RDB 持久化的核心配置(redis.conf)

除了 save 触发条件,redis.conf 中还有多个参数控制 RDB 的行为,关键配置如下:

配置项 作用 默认值 示例
dbfilename 指定 RDB 文件名 dump.rdb dbfilename redis_6379.rdb(按端口命名,便于区分多实例)
dir 指定 RDB 文件的保存目录(必须是目录,不是文件名 .(当前目录) dir /var/lib/redis(推荐配置独立目录)
rdbcompression 是否压缩 RDB 文件(LZF 压缩算法) yes rdbcompression yes(压缩后文件更小,略增加 CPU 开销)
rdbchecksum 是否对 RDB 文件做校验和(CRC64 算法),保证文件完整性 yes rdbchecksum yes(加载时校验,略增加 CPU 开销)
配置生效步骤
  1. 修改 redis.conf 后,重启 Redis 生效:

    bash 复制代码
    redis-server /etc/redis/redis.conf
  2. 验证配置:

    bash 复制代码
    127.0.0.1:6379> CONFIG GET dbfilename
    1) "dbfilename"
    2) "redis_6379.rdb"
    
    127.0.0.1:6379> CONFIG GET dir
    1) "dir"
    2) "/var/lib/redis"

四、RDB 持久化的数据恢复流程

Redis 重启时会自动加载 RDB 文件恢复数据,无需手动操作,恢复流程如下:

  1. Redis 启动时,检查 dir 配置的目录下是否存在 dbfilename 指定的 RDB 文件;
  2. 如果存在,加载 RDB 文件到内存;如果不存在,启动后数据为空;
  3. 加载完成后,Redis 开始接受客户端请求。

注意 :如果 Redis 同时开启了 AOF 持久化 ,则会优先加载 AOF 文件(因为 AOF 数据的实时性更高)。

验证数据恢复
  1. 手动执行 BGSAVE 生成 RDB 文件:

    bash 复制代码
    127.0.0.1:6379> SET name tom  # 写入测试数据
    OK
    127.0.0.1:6379> BGSAVE
    Background saving started
  2. 停止 Redis:

    bash 复制代码
    redis-cli shutdown
  3. 重启 Redis,查看数据是否恢复:

    bash 复制代码
    redis-cli
    127.0.0.1:6379> GET name
    "tom"  # 数据成功恢复

五、RDB 持久化的优缺点

优点
  1. 恢复速度快:RDB 是全量快照文件,Redis 重启时直接加载到内存,比 AOF 逐行重放命令快得多。
  2. 文件体积小 :二进制压缩格式,便于备份、归档和传输(适合用于定时备份)。
  3. 对主进程影响小BGSAVE 由子进程执行,主进程可以正常处理请求。
缺点
  1. 数据安全性低 :RDB 是周期性快照 ,两次快照之间的数据会丢失(比如设置 save 900 1,如果 Redis 崩溃,最多会丢失 15 分钟的数据)。
  2. 大内存实例开销大fork 子进程时,会复制主进程的内存页表,大内存实例(如 10GB 以上)fork 耗时较长,期间 Redis 可能出现短暂卡顿。
  3. 无法实时持久化:不适合对数据实时性要求高的场景(如金融交易)。

六、RDB 持久化的最佳实践(生产环境)

  1. 配合 AOF 使用 :开启 RDB+AOF 混合持久化(Redis 4.0+ 支持),兼顾 RDB 的恢复速度和 AOF 的数据安全性。
  2. 合理配置 save 参数 :避免过于频繁触发 BGSAVE(如不要设置 save 10 1),防止 fork 操作频繁消耗资源;也不要设置太宽松(如 save 3600 1),避免数据丢失过多。
  3. 定期手动备份 RDB 文件 :通过 BGSAVE 生成 RDB 文件后,复制到其他服务器或云存储(如 S3),作为灾难恢复的备份。
  4. 控制 Redis 内存大小 :避免 Redis 内存过大(如超过 10GB),减少 fork 时的内存开销和卡顿时间。
  5. 监控 fork 耗时 :通过 INFO stats 查看 latest_fork_usec(上次 fork 耗时,单位微秒),如果耗时过长(如超过 1 秒),需要优化内存或调整持久化策略。

总结

RDB 持久化是 Redis 的基础持久化方式,核心是通过快照文件保存全量数据,使用时需注意:

  • 手动触发用 BGSAVE,避免 SAVE 阻塞主进程;
  • 自动触发通过 redis.confsave 参数配置,平衡性能和数据安全性;
  • 恢复时 Redis 自动加载 RDB 文件,AOF 开启时优先加载 AOF;
  • 生产环境建议 RDB+AOF 混合持久化,兼顾速度和安全性。
相关推荐
JIngJaneIL2 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
源代码•宸3 小时前
goframe框架签到系统项目(BITFIELD 命令详解、Redis Key 设计、goframe 框架教程、安装MySQL)
开发语言·数据库·经验分享·redis·后端·mysql·golang
天外天-亮3 小时前
v-if、v-show、display: none、visibility: hidden区别
前端·javascript·html
川贝枇杷膏cbppg3 小时前
Redis 的 AOF
java·数据库·redis
jump_jump3 小时前
手写一个 Askama 模板压缩工具
前端·性能优化·rust
be or not to be3 小时前
HTML入门系列:从图片到表单,再到音视频的完整实践
前端·html·音视频
90后的晨仔4 小时前
在macOS上无缝整合:为Claude Code配置魔搭社区免费API完全指南
前端
沿着路走到底4 小时前
JS事件循环
java·前端·javascript
子春一25 小时前
Flutter 2025 可访问性(Accessibility)工程体系:从合规达标到包容设计,打造人人可用的数字产品
前端·javascript·flutter