本文是大数据系列第 46 篇,深入解析 Redis RDB 持久化机制的工作原理、核心配置与生产实践。

完整图文版(含截图):CSDN 原文 | 掘金

什么是 RDB 持久化

RDB(Redis Database)是 Redis 的默认持久化方式,本质是快照(Snapshot):在某一时刻将内存中的所有数据序列化为二进制文件保存到磁盘。触发持久化时,Redis fork 出一个子进程,由子进程将内存数据写入临时文件,完成后原子替换旧文件,整个过程不阻塞父进程的请求处理。

触发方式

自动触发:

  • redis.conf 中配置 save 规则(时间窗口 + 写操作次数阈值)
  • Redis 正常关闭时自动执行

手动触发:

  • SAVE:同步执行,会阻塞所有客户端请求,生产环境慎用
  • BGSAVE:异步后台执行,不影响正常服务
  • FLUSHALL:清空数据库前同样会触发一次 RDB

特殊场景:

  • 主从全量同步时,主节点自动执行 BGSAVE 将 RDB 文件传输给从节点
  • AOF 未开启的情况下 Redis 重启时用 RDB 恢复数据

核心配置参数

# 禁用 RDB(显式关闭)
save ""

# 触发条件:时间窗口(秒)内至少有 N 个 key 被修改
save 900 1      # 15 分钟内至少 1 个 key 变化
save 300 10     # 5 分钟内至少 10 个 key 变化
save 60 10000   # 1 分钟内至少 10000 个 key 变化

# 文件名与存储目录
dbfilename dump.rdb
dir /var/lib/redis

# 启用 LZF 压缩(默认 yes,降低文件体积约 75%)
rdbcompression yes

# 文件末尾写入 CRC64 校验和(默认 yes,防止文件损坏)
rdbchecksum yes

BGSAVE 执行流程

  1. 父进程检查:若已有子进程在执行持久化任务,返回错误
  2. fork 子进程:fork 过程会有短暂阻塞(毫秒级),大内存实例要关注此耗时
  3. 父进程恢复:fork 完成后,父进程立即恢复处理客户端请求
  4. 子进程写入:利用写时复制(Copy-on-Write)机制将内存数据序列化到临时 .rdb 文件
  5. 原子替换:子进程完成后将临时文件 rename 为 dump.rdb
  6. 通知父进程:子进程退出,父进程更新统计信息

写时复制保证了 fork 后父进程的写操作不会影响子进程正在读取的内存页,实现了快照语义的同时也让持久化对主线程的影响降到最低。

RDB 文件结构

字段说明
5 字节魔数固定值 "REDIS"
4 字节版本号RDB 格式版本
辅助字段Redis 版本、创建时间等元数据
数据库编号 + 大小标识数据存储的数据库
过期键信息每个 key 的过期时间戳
键值对数据实际的 key-value 序列化数据
结束标记0xFF
CRC64 校验和文件完整性验证

优缺点分析

优点:

  • 文件紧凑,LZF 压缩后体积约为原始数据的 25%,适合备份和迁移
  • 子进程独立执行,父进程性能不受影响
  • 恢复大数据集速度极快,优于 AOF 重放所有操作
  • 对主线程几乎无干扰

缺点:

  • 两次快照之间的数据有丢失风险(默认配置最多丢 5 分钟数据)
  • fork 操作在大内存实例(数十 GB)上可能耗时数百毫秒,期间服务短暂卡顿
  • 无法做到实时持久化,不适合对数据完整性要求极高的场景

RDB vs AOF

维度RDBAOF
持久化方式数据快照(结果)操作日志(过程)
文件大小小(二进制压缩)大(文本命令)
恢复速度慢(需重放命令)
数据安全低(快照间隔内丢失)高(fsync 每秒/每命令)
写性能影响低(异步 fsync)

混合持久化(Redis 4.0+)

aof-use-rdb-preamble yes

开启混合持久化后,AOF 文件头部存储 RDB 快照内容,后续追加 AOF 增量命令。既保留了 RDB 的快速恢复能力,又具备 AOF 的数据完整性,是生产环境推荐配置。

生产实践建议

  • 大内存实例(> 8 GB)要重点监控 fork 耗时,必要时使用 latency monitor
  • 配合 bgsave 在业务低峰期手动备份,并定期将 dump.rdb 上传至对象存储
  • 对数据安全要求高的场景,建议同时开启 AOF 并使用混合持久化模式
  • 使用 rdbchecksum yes 确保文件完整性,避免因磁盘故障导致的静默损坏