怎样用脚本备份和恢复Redis数据?

wen 实用脚本 5

本文目录导读:

怎样用脚本备份和恢复Redis数据?

  1. 使用 redis-cli 的 RDB 备份方法
  2. 使用 AOF 持久化备份
  3. 使用脚本导出为JSON格式
  4. 自动化备份脚本 (Cron定时)
  5. Cron定时任务配置
  6. 使用建议

我来介绍几种备份和恢复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

使用建议

  1. 备份频率: 根据数据重要性设置,建议至少每天一次
  2. 备份验证: 定期测试恢复过程
  3. 异地备份: 将备份文件同步到其他服务器或云存储
  4. 监控告警: 添加备份失败的告警机制
  5. 测试恢复: 在测试环境定期执行恢复测试

这些脚本可以根据你的实际环境进行调整,记得先测试再在生产环境使用!

抱歉,评论功能暂时关闭!