第五章:持久化机制
深入了解 Redis 的持久化机制:RDB、AOF 以及混合持久化。
最后更新: 2024-01-15
页面目录
Redis 持久化机制
Redis 的持久化机制确保数据在服务器重启后不会丢失。本章详细介绍 RDB、AOF 和混合持久化三种方式。
持久化概述
┌─────────────────────────────────────────────────────────────────┐
│ Redis 持久化方式 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ RDB │ │ AOF │ │
│ │ (快照方式) │ │ (日志方式) │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ └───────────┬───────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ 混合持久化 │ │
│ │ (Redis 4.0+) │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
RDB 持久化
RDB(Redis Database)通过创建数据快照的方式实现持久化。
工作原理
┌─────────────────┐
│ Redis Server │
└────────┬────────┘
│
┌────────▼────────┐
│ fork() 进程 │
└────────┬────────┘
│
┌───────────────────────┼───────────────────────┐
↓ ↓ ↓
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 父进程继续 │ │ 子进程写入 │ │ 写入 dump.rdb │
│ 处理请求 │ │ 内存快照 │ │ │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
↓
┌─────────────────┐
│ 磁盘文件 │
│ dump.rdb │
└─────────────────┘
触发方式
1. 自动触发
# redis.conf
save 900 1 # 900秒内至少1个key变化
save 300 10 # 300秒内至少10个key变化
save 60 10000 # 60秒内至少10000个key变化
2. 手动触发
# 同步保存(阻塞)
SAVE
# 异步保存(后台执行,推荐)
BGSAVE
配置参数
# RDB 文件名
dbfilename dump.rdb
# RDB 文件目录
dir /var/lib/redis
# RDB 压缩
rdbcompression yes
# RDB 校验
rdbchecksum yes
# 失败停止写入
stop-writes-on-bgsave-error yes
优缺点
| 优点 | 缺点 |
|---|---|
| 文件紧凑,适合备份 | 可能丢失最后一次快照后的数据 |
| 恢复速度快 | fork() 时占用内存 |
| 适合灾难恢复 | |
| 适合全量备份 |
AOF 持久化
AOF(Append Only File)通过记录所有写操作命令实现持久化。
工作原理
┌─────────────────────────────────────────────────────────────────┐
│ AOF 工作流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Client → SET key value │
│ │ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ Redis Server │ │
│ └────────┬────────┘ │
│ ↓ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 执行命令 │ ──► │ 追加写入 │ │
│ └─────────────────┘ │ appendonly.aof │ │
│ └─────────────────┘ │
│ │
│ 触发重写时: │
│ ┌─────────────────┐ │
│ │ bgrewriteaof │ │
│ └────────┬────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ 压缩文件 │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
同步策略
# 同步策略
appendonly yes
appendfilename "appendonly.aof"
# 每次写入都同步(最安全,性能最差)
appendfsync always
# 每秒同步(推荐,性能和安全平衡)
appendfsync everysec
# 操作系统决定(性能最好,可能丢失数据)
appendfsync no
AOF 重写
# 自动重写触发条件
auto-aof-rewrite-percentage 100 # 文件比上次大100%时重写
auto-aof-rewrite-min-size 64mb # 文件大于64MB时可能重写
# 忽略最后一条可能被截断的命令
aof-load-truncated yes
# 启用 RDB + AOF 混合持久化(Redis 7.0+)
aof-use-rdb-preamble yes
手动重写
# 手动触发 AOF 重写
BGREWRITEAOF
优缺点
| 优点 | 缺点 |
|---|---|
| 数据安全性更高 | 文件比 RDB 大 |
| 写入策略灵活 | 恢复速度较慢 |
| 尾部追加,效率高 | 可能出现截断问题 |
混合持久化
Redis 4.0 引入混合持久化,结合 RDB 和 AOF 的优点。
工作原理
┌─────────────────────────────────────────────────────────────────┐
│ 混合持久化原理 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 重写时: │
│ ┌─────────────────┐ │
│ │ 生成 RDB 格式 │ │
│ │ 的数据部分 │ │
│ └────────┬────────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ 追加 AOF 格式 │ │
│ │ 的增量命令 │ │
│ └────────┬────────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ 混合文件 │ │
│ │ RDB + AOF │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
文件格式
┌─────────────────────────────────────────────────────────────────┐
│ 混合 AOF 文件格式 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ REDIS (RDB 格式数据) │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ Key 1 │ │ Key 2 │ │ Key 3 │ ← RDB 二进制格式 │ │
│ │ └────────┘ └────────┘ └────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │ │
│ │ *3\r\n$3\r\nSET\r\n... │ │
│ │ *3\r\n$3\r\nSET\r\n... │ │
│ │ ↑ 纯文本 AOF 增量命令 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
配置启用
# 启用混合持久化(Redis 7.0 默认开启)
aof-use-rdb-preamble yes
# 配合 AOF 重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
持久化配置推荐
缓存模式(仅 RDB)
# 适合对数据丢失容忍度较高的场景
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
rdbcompression yes
rdbchecksum yes
生产环境(混合持久化)
# 适合生产环境,推荐配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 混合持久化
aof-use-rdb-preamble yes
aof-load-truncated yes
# 自动重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# RDB 快照
save 900 1
save 300 10
save 60 10000
高性能模式(AOF everysec)
# 追求高性能,适度持久化
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
数据恢复
从 RDB 恢复
# 1. 确保 Redis 已停止
sudo systemctl stop redis
# 2. 备份当前数据
mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak
# 3. 恢复文件
cp /path/to/backup/dump.rdb /var/lib/redis/
# 4. 设置权限
chown redis:redis /var/lib/redis/dump.rdb
# 5. 启动 Redis
sudo systemctl start redis
从 AOF 恢复
# 1. 检查 AOF 文件
redis-check-aof --fix /var/lib/redis/appendonly.aof
# 2. 重启 Redis
sudo systemctl restart redis
从混合持久化恢复
# 自动识别格式并恢复
redis-server /etc/redis/redis.conf
redis-cli
# 验证数据
KEYS *
备份策略
定时备份脚本
#!/bin/bash
# redis-backup.sh
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)
KEEP_DAYS=30
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 触发 BGSAVE
redis-cli BGSAVE
# 等待保存完成
while [ $(redis-cli LASTSAVE) == $(redis-cli -c LASTSAVE) ]; do
sleep 1
done
# 复制 RDB 文件
cp /var/lib/redis/dump.rdb ${BACKUP_DIR}/dump_${DATE}.rdb
# 复制 AOF 文件(如果启用)
if [ -f /var/lib/redis/appendonly.aof ]; then
cp /var/lib/redis/appendonly.aof ${BACKUP_DIR}/appendonly_${DATE}.aof
fi
# 创建压缩包
cd ${BACKUP_DIR}
tar czf redis_backup_${DATE}.tar.gz dump_${DATE}.rdb
[ -f appendonly_${DATE}.aof ] && tar czf redis_backup_${DATE}.tar.gz dump_${DATE}.rdb appendonly_${DATE}.aof
# 清理临时文件
rm -f dump_${DATE}.rdb appendonly_${DATE}.aof
# 上传到远程存储
# aws s3 cp redis_backup_${DATE}.tar.gz s3://my-bucket/redis/
# 清理旧备份
find ${BACKUP_DIR} -name "redis_backup_*.tar.gz" -mtime +${KEEP_DAYS} -delete
echo "备份完成: redis_backup_${DATE}.tar.gz"
Crontab 配置
# 每天凌晨 2 点备份
0 2 * * * /opt/scripts/redis-backup.sh >> /var/log/redis-backup.log 2>&1
性能影响
| 持久化方式 | fork() | I/O 操作 | 内存占用 |
|---|---|---|---|
| RDB | 是 | 一次性 | 2倍 |
| AOF everysec | 否 | 每秒 | 追加 |
| 混合持久化 | 是 | 一次性+追加 | 适中 |
下一步
接下来让我们学习 Redis 的主从复制。
👉 主从复制