本文是大数据系列第 46 篇,深入解析 Redis RDB 持久化机制的工作原理、核心配置与生产实践。
什么是 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 执行流程
- 父进程检查:若已有子进程在执行持久化任务,返回错误
- fork 子进程:fork 过程会有短暂阻塞(毫秒级),大内存实例要关注此耗时
- 父进程恢复:fork 完成后,父进程立即恢复处理客户端请求
- 子进程写入:利用写时复制(Copy-on-Write)机制将内存数据序列化到临时
.rdb文件 - 原子替换:子进程完成后将临时文件 rename 为
dump.rdb - 通知父进程:子进程退出,父进程更新统计信息
写时复制保证了 fork 后父进程的写操作不会影响子进程正在读取的内存页,实现了快照语义的同时也让持久化对主线程的影响降到最低。
RDB 文件结构
| 字段 | 说明 |
|---|---|
| 5 字节魔数 | 固定值 "REDIS" |
| 4 字节版本号 | RDB 格式版本 |
| 辅助字段 | Redis 版本、创建时间等元数据 |
| 数据库编号 + 大小 | 标识数据存储的数据库 |
| 过期键信息 | 每个 key 的过期时间戳 |
| 键值对数据 | 实际的 key-value 序列化数据 |
| 结束标记 | 0xFF |
| CRC64 校验和 | 文件完整性验证 |
优缺点分析
优点:
- 文件紧凑,LZF 压缩后体积约为原始数据的 25%,适合备份和迁移
- 子进程独立执行,父进程性能不受影响
- 恢复大数据集速度极快,优于 AOF 重放所有操作
- 对主线程几乎无干扰
缺点:
- 两次快照之间的数据有丢失风险(默认配置最多丢 5 分钟数据)
- fork 操作在大内存实例(数十 GB)上可能耗时数百毫秒,期间服务短暂卡顿
- 无法做到实时持久化,不适合对数据完整性要求极高的场景
RDB vs AOF
| 维度 | RDB | AOF |
|---|---|---|
| 持久化方式 | 数据快照(结果) | 操作日志(过程) |
| 文件大小 | 小(二进制压缩) | 大(文本命令) |
| 恢复速度 | 快 | 慢(需重放命令) |
| 数据安全 | 低(快照间隔内丢失) | 高(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确保文件完整性,避免因磁盘故障导致的静默损坏