Redis自动备份脚本
Redis数据库自动备份脚本,支持RDB和AOF两种备份方式,自动压缩、清理旧备份、备份验证,支持远程备份和告警通知
详细内容
#!/bin/bash
# ==========================================
# Redis自动备份脚本
# 用途:自动备份Redis数据,支持RDB/AOF,自动压缩清理
# 使用方法:加入crontab每天凌晨执行
# ==========================================
# ========== 配置 ==========
REDIS_HOST="127.0.0.1"
REDIS_PORT=6379
REDIS_PASSWORD=""
REDIS_CLI="redis-cli"
BACKUP_DIR="/backup/redis"
BACKUP_PREFIX="redis_backup"
KEEP_DAYS=7 # 保留天数
RDB_FILE="/var/lib/redis/dump.rdb" # RDB文件路径
AOF_FILE="/var/lib/redis/appendonly.aof" # AOF文件路径
BACKUP_TYPE="both" # rdb / aof / both
LOG_FILE="/var/log/redis_backup.log"
ALERT_EMAIL=""
# ==========================
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
send_alert() {
local title="$1"
local content="$2"
log_msg "【告警】$title: $content"
if [ -n "$ALERT_EMAIL" ]; then
echo -e "$content" | mail -s "【Redis备份】$title" "$ALERT_EMAIL" 2>/dev/null
fi
}
# 检查redis-cli
if ! command -v "$REDIS_CLI" >/dev/null 2>&1; then
log_msg "❌ redis-cli未安装"
exit 1
fi
# 连接参数
CONN_PARAMS="-h $REDIS_HOST -p $REDIS_PORT"
if [ -n "$REDIS_PASSWORD" ]; then
CONN_PARAMS="$CONN_PARAMS -a $REDIS_PASSWORD"
fi
# 检查Redis连接
if ! $REDIS_CLI $CONN_PARAMS ping >/dev/null 2>&1; then
log_msg "❌ 无法连接Redis: $REDIS_HOST:$REDIS_PORT"
send_alert "Redis备份失败" "无法连接Redis服务器: $REDIS_HOST:$REDIS_PORT"
exit 1
fi
DATE=$(date '+%Y%m%d_%H%M%S')
log_msg "===== Redis备份开始 ====="
log_msg "备份类型: $BACKUP_TYPE"
log_msg "Redis: $REDIS_HOST:$REDIS_PORT"
# 获取Redis信息
REDIS_VERSION=$($REDIS_CLI $CONN_PARAMS info server 2>/dev/null | grep "redis_version" | cut -d: -f2 | tr -d '\r')
DB_SIZE=$($REDIS_CLI $CONN_PARAMS dbsize 2>/dev/null)
log_msg "Redis版本: $REDIS_VERSION"
log_msg "当前key数量: $DB_SIZE"
BACKUP_SUCCESS=true
# RDB备份
if [ "$BACKUP_TYPE" = "rdb" ] || [ "$BACKUP_TYPE" = "both" ]; then
log_msg "--- RDB备份 ---"
# 触发BGSAVE
$REDIS_CLI $CONN_PARAMS bgsave >/dev/null 2>&1
log_msg "已触发BGSAVE,等待完成..."
# 等待BGSAVE完成
for i in $(seq 1 60); do
LAST_SAVE=$($REDIS_CLI $CONN_PARAMS lastsave 2>/dev/null)
BGSAVE_STATUS=$($REDIS_CLI $CONN_PARAMS info persistence 2>/dev/null | grep "rdb_bgsave_in_progress" | cut -d: -f2 | tr -d '\r')
if [ "$BGSAVE_STATUS" = "0" ]; then
log_msg "BGSAVE完成"
break
fi
sleep 2
done
# 复制RDB文件
if [ -f "$RDB_FILE" ]; then
RDB_BACKUP="$BACKUP_DIR/${BACKUP_PREFIX}_${DATE}.rdb"
cp "$RDB_FILE" "$RDB_BACKUP"
if [ -f "$RDB_BACKUP" ]; then
gzip -f "$RDB_BACKUP"
RDB_SIZE=$(du -h "${RDB_BACKUP}.gz" | awk '{print $1}')
log_msg "✓ RDB备份成功: ${RDB_BACKUP}.gz ($RDB_SIZE)"
else
log_msg "✗ RDB备份文件复制失败"
BACKUP_SUCCESS=false
fi
else
log_msg "✗ RDB文件不存在: $RDB_FILE"
BACKUP_SUCCESS=false
fi
fi
# AOF备份
if [ "$BACKUP_TYPE" = "aof" ] || [ "$BACKUP_TYPE" = "both" ]; then
log_msg "--- AOF备份 ---"
if [ -f "$AOF_FILE" ]; then
AOF_BACKUP="$BACKUP_DIR/${BACKUP_PREFIX}_${DATE}.aof"
cp "$AOF_FILE" "$AOF_BACKUP"
if [ -f "$AOF_BACKUP" ]; then
gzip -f "$AOF_BACKUP"
AOF_SIZE=$(du -h "${AOF_BACKUP}.gz" | awk '{print $1}')
log_msg "✓ AOF备份成功: ${AOF_BACKUP}.gz ($AOF_SIZE)"
else
log_msg "✗ AOF备份文件复制失败"
BACKUP_SUCCESS=false
fi
else
log_msg "⚠️ AOF文件不存在,跳过AOF备份(可能未开启AOF持久化)"
fi
fi
# 清理旧备份
log_msg "--- 清理旧备份 ---"
DELETED=$(find "$BACKUP_DIR" -name "${BACKUP_PREFIX}_*" -mtime +$KEEP_DAYS -print -delete | wc -l)
log_msg "已删除 $DELETED 个超过${KEEP_DAYS}天的旧备份"
# 备份统计
log_msg "--- 备份统计 ---"
TOTAL_FILES=$(find "$BACKUP_DIR" -name "${BACKUP_PREFIX}_*" | wc -l)
TOTAL_SIZE=$(du -sh "$BACKUP_DIR" | awk '{print $1}')
log_msg "备份文件总数: $TOTAL_FILES"
log_msg "备份目录大小: $TOTAL_SIZE"
if [ "$BACKUP_SUCCESS" = true ]; then
log_msg "===== Redis备份完成 ✓ ====="
else
log_msg "===== Redis备份完成(存在失败项)⚠️ ====="
send_alert "Redis备份存在失败项" "备份过程中有部分操作失败,请查看日志: $LOG_FILE"
fi
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "REDIS_HOST", "label": "Redis\u4e3b\u673a", "default": "127.0.0.1"}, {"name": "REDIS_PORT", "label": "Redis\u7aef\u53e3", "default": "6379"}, {"name": "REDIS_PASSWORD", "label": "Redis\u5bc6\u7801(\u53ef\u9009)", "default": ""}, {"name": "BACKUP_DIR", "label": "\u5907\u4efd\u76ee\u5f55", "default": "/backup/redis"}, {"name": "KEEP_DAYS", "label": "\u4fdd\u7559\u5929\u6570", "default": "7"}, {"name": "BACKUP_TYPE", "label": "\u5907\u4efd\u7c7b\u578b(rdb/aof/both)", "default": "both"}]