RDB持久化
RDB(Redis Database)是将Redis内存数据以快照形式保存到磁盘的二进制文件,恢复时直接加载到内存。
RDB原理
快照机制
Bash
RDB流程:
1. Redis调用fork创建子进程
2. 子进程将内存数据写入临时文件
3. 写入完成后重命名为RDB文件
4. 主进程继续处理请求(不阻塞)
fork机制
Bash
fork特点:
- 创建进程副本
- 子进程共享父进程内存页
- 写时复制(Copy-on-Write)
- 父进程修改数据时复制内存页
fork期间主进程可能短暂阻塞(毫秒级),内存越大阻塞时间越长。
RDB触发方式
自动触发(save规则)
Bash
# redis.conf配置
save 900 1 # 900秒内至少1次修改触发
save 300 10 # 300秒内至少10次修改触发
save 60 10000 # 60秒内至少10000次修改触发
# 禁用自动保存
save ""
手动触发
Bash
# SAVE:同步保存(阻塞主进程)
SAVE
# BGSAVE:后台保存(不阻塞)
BGSAVE
# 查看后台保存状态
LASTSAVE
# 返回上次保存的时间戳
生产环境使用BGSAVE,SAVE会阻塞所有请求。
其他触发场景
Bash
- FLUSHALL触发保存(空文件)
- 主从复制时主节点执行BGSAVE
- Redis正常关闭时执行保存
- debug reload重启触发
RDB文件结构
文件格式
Bash
RDB文件结构:
┌─────────────────────────────────┐
│ REDIS版本号 │
┌─────────────────────────────────┐
│ 数据库编号 │
┌─────────────────────────────────┐
│ 数据库大小 │
┌─────────────────────────────────┐
│ key-value数据 │
┌─────────────────────────────────┐
│ 结束标志 + 校验值 │
└─────────────────────────────────┘
数据编码
Bash
每个key-value的存储:
- key类型标识
- key字符串
- value数据(根据类型编码)
- 过期时间(如有)
查看RDB内容
Bash
# 使用redis-check-rdb
redis-check-rdb dump.rdb
# 使用rdb工具解析
rdb --command json dump.rdb
RDB配置
核心配置项
Bash
# RDB文件名
dbfilename dump.rdb
# 文件存储目录
dir /var/lib/redis
# 是否压缩
rdbcompression yes
# 是否校验
rdbchecksum yes
# fork失败时停止写入(避免数据丢失)
stop-writes-on-bgsave-error yes
压缩配置
Bash
# 启用LZF压缩
rdbcompression yes
# 压缩优点:文件更小
# 压缩缺点:CPU消耗增加
校验配置
Bash
# 启用CRC64校验
rdbchecksum yes
# 校验优点:文件完整性保证
# 校验缺点:保存和加载时消耗CPU
RDB优点
优点列表
Bash
1. 文件紧凑
- 二进制格式,体积小
- 适合备份和传输
2. 恢复快速
- 直接加载到内存
- 恢复速度远快于AOF
3. 对性能影响小
- 子进程fork后主进程继续服务
- 只短暂阻塞fork
4. 适合灾难恢复
- 文件可快速复制
- 跨机器迁移方便
恢复效率对比
Bash
RDB恢复:GB级数据几秒到几十秒
AOF恢复:GB级数据几分钟到几十分钟
RDB缺点
缺点列表
Bash
1. 数据安全性低
- 可能丢失最后一次保存后的数据
- save规则间隔越长,丢失越多
2. fork开销
- 内存大时fork耗时
- fork期间短暂阻塞
- 写时复制可能消耗大量内存
3. 不适合实时持久化
- 定时保存,非实时
- 无法做到秒级数据安全
数据丢失场景
Bash
最后一次保存后:
- 新增的key丢失
- 修改的值丢失
- 删除的key可能恢复回来
save 900 1配置下:
- 可能丢失15分钟数据
fork问题
text
内存越大,fork越慢:
- 4GB内存:fork约几十毫秒
- 32GB内存:fork可能几百毫秒
- 写时复制:修改的内存页会复制
建议:
- 控制内存使用
- 避免save间隔内大量写入
RDB恢复
恢复流程
text
# 1. 将RDB文件放到数据目录
cp dump.rdb /var/lib/redis/
# 2. 启动Redis自动加载
redis-server
# Redis启动时检测RDB文件存在则自动加载
恢复优先级
text
Redis启动加载顺序:
1. 如果开启AOF,优先加载AOF
2. 如果只开启RDB,加载RDB
3. 两者都开启,优先加载AOF
文件校验
text
# 检查RDB文件完整性
redis-check-rdb dump.rdb
# 输出结果:
# [offset 0] Checking RDB file dump.rdb
# [offset 26] AUX FIELD redis-ver ...
# RDB file is OK
RDB文件管理
定期备份
text
# 定时备份脚本
#!/bin/bash
DATE=$(date +%Y%m%d%H%M)
cp /var/lib/redis/dump.rdb /backup/dump.rdb.$DATE
# 保留最近7天备份
find /backup -name "dump.rdb.*" -mtime +7 -delete
跨机房备份
text
# 同步到备份服务器
rsync -avz /var/lib/redis/dump.rdb backup-server:/backup/redis/
多版本管理
text
# 每小时备份
0 * * * * cp /var/lib/redis/dump.rdb /backup/hourly/dump.rdb
# 每日备份
0 0 * * * cp /var/lib/redis/dump.rdb /backup/daily/dump.rdb.$(date +%Y%m%d)
性能优化
fork优化
text
# 禁用THP(减少fork延迟)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 调整内核参数
sysctl -w vm.overcommit_memory=1
save规则优化
text
# 根据业务特点调整
# 写入频繁:缩短间隔
save 300 100
# 写入稀疏:延长间隔
save 900 1
# 平衡数据安全和性能
内存优化
text
# 控制内存使用
maxmemory 4gb
# 减少fork开销
# 内存控制在合理范围
监控指标
INFO命令查看
text
INFO persistence
# 关键指标
rdb_last_save_time: 上次保存时间戳
rdb_changes_since_last_save: 上次保存后的修改次数
rdb_bgsave_in_progress: 是否正在执行BGSAVE
rdb_last_bgsave_status: 上次BGSAVE状态(ok/err)
rdb_last_bgsave_time_sec: 上次BGSAVE耗时(秒)
监控告警
text
- BGSAVE失败告警
- BGSAVE耗时过长告警(>60秒)
- 修改次数过多但未保存告警
要点总结
- RDB是快照持久化,fork子进程生成二进制文件
- save规则自动触发,BGSAVE手动后台触发
- 优点:文件紧凑、恢复快速、对性能影响小
- 缺点:可能丢失最后一次保存后的数据、fork有开销
- 配置save规则平衡数据安全和性能
- 内存越大fork越慢,控制内存使用
- 启动时AOF优先级高于RDB
- 定期备份RDB文件,保留多版本
- 监控BGSAVE状态和耗时,异常告警
📝 发现内容有误?点击此处直接编辑