如何备份 Redis 缓存数据?(完整指南 + 生产实践)
Redis 虽然常被用作“缓存”,但在许多生产场景中(如会话存储、限流计数、实时 lookup 表),其数据具有重要业务价值。一旦 Redis 故障或误操作,可能导致服务异常。
因此,定期备份 Redis 数据是保障系统可靠性的重要措施。
本文将详细介绍 Redis 数据备份的 5 种方法,包括 RDB、AOF、复制、快照工具和导出脚本,并提供 自动化备份脚本、恢复流程、最佳实践 等企业级方案。
一、Redis 数据持久化机制(备份基础)
Redis 提供两种内置持久化方式:
| 机制 | 说明 | 是否适合备份 |
|---|---|---|
| ✅ RDB(Redis Database) | 定期生成内存快照 .rdb 文件 | ✅ 推荐用于备份 |
| ✅ AOF(Append Only File) | 记录所有写操作日志 | ✅ 可用于恢复到任意时间点 |
| ❌ 复制(Replication) | 主从同步,非持久化 | ❌ 不是备份 |
🔑 生产环境应同时启用 RDB + AOF
二、方法一:RDB 快照备份(推荐用于定期备份)
2.1 原理
Redis 周期性将内存数据生成二进制快照文件(如 dump.rdb)。
2.2 配置 redis.conf
# 启用 RDB
save 900 1 # 15分钟内至少1次修改
save 300 10 # 5分钟内至少10次修改
save 60 10000 # 1分钟内至少1万次修改
# RDB 文件名
dbfilename dump.rdb
# RDB 文件路径
dir /var/lib/redis
# 启用压缩
rdbcompression yes
# 校验 CRC64(v5+)
rdbchecksum yes
2.3 手动触发快照
redis-cli SAVE # 同步阻塞(不推荐)
redis-cli BGSAVE # 后台异步保存(推荐)
2.4 自动化备份脚本(Shell)
#!/bin/bash
# backup_redis_rdb.sh
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)
REDIS_CLI="/usr/local/bin/redis-cli"
RDB_FILE="/var/lib/redis/dump.rdb"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 触发异步快照
$REDIS_CLI BGSAVE
# 等待完成(可优化为轮询 INFO persistence)
sleep 10
# 复制 RDB 文件并压缩
if [ -f "$RDB_FILE" ]; then
cp $RDB_FILE $BACKUP_DIR/dump-$DATE.rdb
gzip $BACKUP_DIR/dump-$DATE.rdb
echo "✅ RDB Backup saved: $BACKUP_DIR/dump-$DATE.rdb.gz"
else
echo "❌ RDB file not found!"
exit 1
fi
# 清理 7 天前的备份
find $BACKUP_DIR -name "dump-*.rdb.gz" -mtime +7 -delete
2.5 加入定时任务
# 每天凌晨 2 点备份
0 2 * * * /path/to/backup_redis_rdb.sh >> /var/log/redis-backup.log 2>&1
三、方法二:AOF 日志备份(适合精确恢复)
3.1 原理
AOF 记录所有写命令,可重放恢复数据。
3.2 配置 redis.conf
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # 推荐:每秒同步一次
# AOF 重写(压缩日志)
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
3.3 备份 AOF 文件
# 复制 AOF 文件(需先重写以压缩)
redis-cli BGREWRITEAOF
sleep 5
cp /var/lib/redis/appendonly.aof /backup/aof/appendonly-$(date +%Y%m%d).aof
gzip /backup/aof/appendonly-$(date +%Y%m%d).aof
⚠️ AOF 文件可能很大,建议配合
BGREWRITEAOF使用。
四、方法三:使用 redis-rdb-tools 导出为 JSON(可读备份)
适合需要 人类可读、跨系统迁移 的场景。
4.1 安装工具
pip install rdbtools
4.2 导出为 JSON
# 将 RDB 转为 JSON
rdb --command json /var/lib/redis/dump.rdb > backup.json
# 只导出特定 key(支持正则)
rdb --command json --key "session:*" /var/lib/redis/dump.rdb > sessions.json
4.3 从 JSON 恢复(Python 脚本)
import json
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
with open('backup.json', 'r') as f:
data = json.load(f)
for entry in data:
key = entry['key']
value = entry['value']
ttl = entry.get('expired', 0) # 过期时间
if entry['type'] == 'string':
r.set(key, value)
elif entry['type'] == 'hash':
r.hset(key, mapping=value)
if ttl > 0:
r.expireat(key, ttl)
五、方法四:主从复制 + 备份从节点(生产推荐)
架构:
[Master] ← replication → [Slave]
↓
[Backup Job]
优点:
- 不影响主节点性能
- 可在从节点执行
BGSAVE而不阻塞主库
脚本示例:
#!/bin/bash
# 在从节点执行
redis-cli SLAVEOF NO ONE # 断开复制(可选)
redis-cli BGSAVE
# ... 备份 RDB
redis-cli SLAVEOF master-ip 6379 # 重新复制(可选)
⚠️ 注意:断开复制可能导致主从不一致,建议在维护窗口操作。
六、方法五:使用云服务或企业工具
| 工具 | 说明 |
|---|---|
| AWS ElastiCache | 自动快照,保留 1~35 天 |
| 阿里云 Redis | 支持自动备份、跨区域复制 |
| Redis Enterprise | 提供 PITR(Point-in-Time Recovery) |
| Velero(K8s) | 备份 Redis StatefulSet 卷 |
适合云原生环境。
七、恢复数据流程
7.1 从 RDB 恢复
# 停止 Redis
systemctl stop redis
# 替换 dump.rdb
cp /backup/dump-20250405.rdb /var/lib/redis/dump.rdb
# 启动 Redis
systemctl start redis
7.2 从 AOF 恢复
# 停止 Redis
systemctl stop redis
# 替换 AOF 文件
cp /backup/appendonly.aof /var/lib/redis/appendonly.aof
# 启动 Redis(自动重放 AOF)
systemctl start redis
7.3 从 JSON 恢复
使用上文的 Python 脚本导入。
八、备份策略最佳实践
| 项目 | 推荐做法 |
|---|---|
| 频率 | RDB 每日 1~2 次,AOF 实时 |
| 保留周期 | 至少 7 天,关键数据 30 天 |
| 存储位置 | 异地(如 S3、NAS),避免同机房 |
| 加密 | 备份文件使用 GPG 或 AES 加密 |
| 验证 | 定期恢复测试(如每月一次) |
| 监控 | 监控备份是否成功、文件大小异常 |
九、自动化备份脚本模板(增强版)
#!/bin/bash
# enhanced_redis_backup.sh
set -euo pipefail
BACKUP_ROOT="/backup/redis"
ENCRYPT_KEY="your-secret-key" # 用于 gpg
S3_BUCKET="s3://my-backup-bucket/redis"
# 创建目录
mkdir -p $BACKUP_ROOT/in_progress
# 时间戳
TS=$(date +%Y%m%d-%H%M%S)
RDB_SRC="/var/lib/redis/dump.rdb"
RDB_BAK="$BACKUP_ROOT/in_progress/dump-$TS.rdb"
# 1. 触发备份
echo "🔄 Triggering BGSAVE..."
redis-cli BGSAVE || { echo "BGSAVE failed"; exit 1; }
# 2. 等待完成(轮询)
echo "⏳ Waiting for BGSAVE to complete..."
while [[ $(redis-cli info persistence | grep rdb_bgsave_in_progress | cut -d: -f2) == "1" ]]; do
sleep 2
done
# 3. 检查文件
if [[ ! -f "$RDB_SRC" ]]; then
echo "❌ RDB file not generated!"
exit 1
fi
# 4. 复制并压缩
cp "$RDB_SRC" "$RDB_BAK"
gzip "$RDB_BAK"
ENCRYPTED_FILE="$RDB_BAK.gz.gpg"
# 5. 加密(可选)
gpg --batch --yes --passphrase "$ENCRYPT_KEY" --symmetric --cipher-algo AES256 "$RDB_BAK.gz"
# 6. 上传到 S3
aws s3 cp "$ENCRYPTED_FILE" "$S3_BUCKET/" || echo "⚠️ Upload failed"
# 7. 清理
rm -f "$RDB_BAK.gz" "$ENCRYPTED_FILE"
find $BACKUP_ROOT -name "*.rdb.gz" -mtime +7 -delete
echo "✅ Backup completed: $ENCRYPTED_FILE"
十、常见问题与解决方案
| 问题 | 解决方案 |
|---|---|
BGSAVE failed | 检查磁盘空间、权限 |
| 备份文件损坏 | 使用 rdb --check 验证 |
| 恢复后数据不全 | 检查是否启用了 AOF |
| 备份太大 | 使用 redis-rdb-tools 过滤 key |
| 权限错误 | 确保备份用户有读取 RDB 权限 |
十一、结语
Redis 虽然是内存数据库,但 “缓存” ≠ “可丢弃”。通过以下组合策略,可实现高可靠备份:
🔑 推荐方案:
- RDB + AOF 双持久化
- 每日 RDB 备份 + 异地存储
- 定期恢复演练
记住:没有备份的数据库,等于没有数据。
1030

被折叠的 条评论
为什么被折叠?



