本文目录导读:

我来介绍几种备份和恢复Redis数据的脚本方法。
使用 redis-cli 的 RDB 备份方法
备份脚本 (backup_redis.sh)
#!/bin/bash
# Redis 连接信息
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD="" # 如果没有密码留空
# 备份目录
BACKUP_DIR="/data/redis_backup"
DATE=$(date +%Y%m%d_%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR
# 方式1: 使用 SAVE 命令(阻塞式)
echo "开始RDB备份..."
if [ -z "$REDIS_PASSWORD" ]; then
redis-cli -h $REDIS_HOST -p $REDIS_PORT SAVE
else
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD SAVE
fi
# 复制dump文件到备份目录
cp /var/lib/redis/dump.rdb $BACKUP_DIR/redis_backup_$DATE.rdb
# 方式2: 使用 BGSAVE(非阻塞式,推荐)
echo "开始BGSAVE备份..."
if [ -z "$REDIS_PASSWORD" ]; then
redis-cli -h $REDIS_HOST -p $REDIS_PORT BGSAVE
else
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD BGSAVE
fi
# 等待BGSAVE完成
sleep 2
# 删除30天前的备份
find $BACKUP_DIR -name "redis_backup_*.rdb" -mtime +30 -delete
echo "备份完成: $BACKUP_DIR/redis_backup_$DATE.rdb"
恢复脚本 (restore_redis.sh)
#!/bin/bash
# Redis 连接信息
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD=""
# 检查是否提供了备份文件
if [ $# -ne 1 ]; then
echo "用法: $0 <备份文件路径>"
exit 1
fi
BACKUP_FILE=$1
if [ ! -f "$BACKUP_FILE" ]; then
echo "错误: 备份文件 $BACKUP_FILE 不存在"
exit 1
fi
# 停止Redis服务
echo "停止Redis服务..."
systemctl stop redis
# 备份当前数据(以防万一)
cp /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak
# 复制备份文件到Redis数据目录
echo "恢复数据..."
cp $BACKUP_FILE /var/lib/redis/dump.rdb
# 设置正确的权限
chown redis:redis /var/lib/redis/dump.rdb
chmod 640 /var/lib/redis/dump.rdb
# 启动Redis服务
echo "启动Redis服务..."
systemctl start redis
# 验证恢复是否成功
sleep 2
if [ -z "$REDIS_PASSWORD" ]; then
redis-cli -h $REDIS_HOST -p $REDIS_PORT PING
else
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD PING
fi
if [ $? -eq 0 ]; then
echo "Redis服务启动成功,恢复完成!"
else
echo "错误: Redis服务启动失败,请检查日志"
# 恢复备份
echo "正在恢复原始数据..."
cp /var/lib/redis/dump.rdb.bak /var/lib/redis/dump.rdb
systemctl restart redis
fi
使用 AOF 持久化备份
AOF 备份脚本
#!/bin/bash
# Redis 信息
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD=""
# 备份目录
BACKUP_DIR="/data/redis_backup"
DATE=$(date +%Y%m%d_%H%M%S)
# 执行AOF重写
echo "开始AOF重写..."
if [ -z "$REDIS_PASSWORD" ]; then
redis-cli -h $REDIS_HOST -p $REDIS_PORT BGREWRITEAOF
else
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD BGREWRITEAOF
fi
# 等待AOF重写完成
sleep 3
# 备份AOF文件
cp /var/lib/redis/appendonly.aof $BACKUP_DIR/appendonly_$DATE.aof
echo "AOF备份完成: $BACKUP_DIR/appendonly_$DATE.aof"
使用脚本导出为JSON格式
#!/usr/bin/env python3
# redis_backup_json.py
import redis
import json
import datetime
import os
class RedisBackup:
def __init__(self, host='localhost', port=6379, password=None):
self.redis = redis.Redis(
host=host,
port=port,
password=password,
decode_responses=True
)
def export_all_data(self, output_file=None):
"""导出所有数据到JSON文件"""
data = {}
# 获取所有key
cursor = 0
while True:
cursor, keys = self.redis.scan(cursor, count=1000)
for key in keys:
key_type = self.redis.type(key)
data[key] = self._get_key_value(key, key_type)
if cursor == 0:
break
if output_file is None:
output_file = f"redis_backup_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print(f"导出完成: {output_file}")
return output_file
def _get_key_value(self, key, key_type):
"""根据key类型获取值"""
if key_type == 'string':
return self.redis.get(key)
elif key_type == 'list':
return self.redis.lrange(key, 0, -1)
elif key_type == 'set':
return list(self.redis.smembers(key))
elif key_type == 'zset':
return self.redis.zrange(key, 0, -1, withscores=True)
elif key_type == 'hash':
return self.redis.hgetall(key)
else:
return None
def import_from_json(self, json_file):
"""从JSON文件导入数据"""
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
# 清空Redis(谨慎使用)
# self.redis.flushall()
for key, value in data.items():
if isinstance(value, str):
self.redis.set(key, value)
elif isinstance(value, list):
if value and isinstance(value[0], (tuple, list)):
# ZSET
self.redis.zadd(key, dict(value))
else:
# LIST或SET
if self.redis.type(key) == 'set':
self.redis.sadd(key, *value)
else:
self.redis.rpush(key, *value)
elif isinstance(value, dict):
self.redis.hset(key, mapping=value)
print(f"导入完成: {json_file}")
# 使用示例
if __name__ == "__main__":
backup = RedisBackup()
# 导出
backup.export_all_data()
# 导入
# backup.import_from_json('redis_backup_20231201_120000.json')
自动化备份脚本 (Cron定时)
#!/bin/bash
# auto_backup.sh - 配合cron使用的自动化备份
REDIS_HOST="localhost"
REDIS_PORT="6379"
BACKUP_DIR="/data/redis_backup"
LOG_FILE="/var/log/redis_backup.log"
MAX_BACKUPS=7 # 保留最近7天的备份
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}
# 创建备份目录
mkdir -p $BACKUP_DIR
log "开始Redis备份..."
# 触发RDB备份
redis-cli -h $REDIS_HOST -p $REDIS_PORT BGSAVE
if [ $? -ne 0 ]; then
log "错误: BGSAVE 失败"
exit 1
fi
# 等待备份完成
sleep 5
# 获取最新的dump文件
RDB_FILE=$(ls -t /var/lib/redis/dump.rdb 2>/dev/null)
if [ -f "$RDB_FILE" ]; then
BACKUP_FILE="$BACKUP_DIR/redis_$(date +%Y%m%d_%H%M%S).rdb"
cp $RDB_FILE $BACKUP_FILE
log "备份已保存到: $BACKUP_FILE"
else
log "错误: 找不到dump.rdb文件"
exit 1
fi
# 删除旧备份
cd $BACKUP_DIR
ls -t | tail -n +$((MAX_BACKUPS + 1)) | xargs -I {} rm -f {}
log "清理完成,保留最近 $MAX_BACKUPS 个备份"
# 检查备份文件完整性
if [ -f "$BACKUP_FILE" ]; then
FILE_SIZE=$(stat -c%s "$BACKUP_FILE")
log "备份文件大小: $FILE_SIZE bytes"
if [ $FILE_SIZE -gt 0 ]; then
log "备份成功完成!"
else
log "警告: 备份文件大小为0"
fi
fi
Cron定时任务配置
# 编辑crontab crontab -e # 每天凌晨2点执行备份 0 2 * * * /path/to/auto_backup.sh # 每6小时执行一次 0 */6 * * * /path/to/auto_backup.sh # 每周日晚上11点执行 0 23 * * 0 /path/to/auto_backup.sh
使用建议
- 备份频率: 根据数据重要性设置,建议至少每天一次
- 备份验证: 定期测试恢复过程
- 异地备份: 将备份文件同步到其他服务器或云存储
- 监控告警: 添加备份失败的告警机制
- 测试恢复: 在测试环境定期执行恢复测试
这些脚本可以根据你的实际环境进行调整,记得先测试再在生产环境使用!