如何监控 Redis 备份完整性?(企业级监控方案)
在生产环境中,“做了备份” ≠ “备份可用”。许多灾难恢复失败的根源是:备份文件损坏、未按时生成、恢复流程未验证。
本文将详细介绍 如何全面监控 Redis 备份的完整性,涵盖 文件存在性、校验和验证、恢复演练、日志审计、自动化告警 等关键环节,并提供可落地的 Shell/Python 脚本和监控集成方案。
一、备份完整性的五大维度
| 维度 | 监控内容 | 工具示例 |
|---|---|---|
| ✅ 存在性(Existence) | 备份文件是否按时生成 | ls, find |
| ✅ 完整性(Integrity) | 文件是否损坏、可读 | redis-check-rdb, gzip -t |
| ✅ 一致性(Consistency) | 全量 + 增量是否连续 | 时间戳检查 |
| ✅ 可恢复性(Restorability) | 能否成功恢复 | 恢复演练脚本 |
| ✅ 安全性(Security) | 是否加密、权限正确 | gpg --verify, stat |
🔑 核心原则:不验证的备份,等于没有备份
二、监控策略与实现
2.1 策略一:文件存在性监控
目标:
确保每日/每小时备份文件按时生成。
实现脚本(Shell)
#!/bin/bash
# check_backup_existence.sh
BACKUP_DIR="/backup/redis"
HOURS=24 # 检查过去 24 小时
# 检查是否有今天的 RDB 备份
if find "$BACKUP_DIR" -name "dump-$(date +%Y%m%d)*.rdb.gz" -mmin -$((HOURS * 60)) | grep -q .; then
echo "✅ RDB backup exists"
exit 0
else
echo "❌ No RDB backup found in last $HOURS hours"
exit 1
fi
加入监控系统(如 Prometheus)
# 输出为 Prometheus 格式
echo 'redis_backup_exists 1' > /tmp/redis_backup.prom
2.2 策略二:文件完整性校验
目标:
验证备份文件未损坏,可被 Redis 正确解析。
使用 redis-check-rdb 验证 RDB
#!/bin/bash
# verify_rdb_integrity.sh
RDB_FILE="$1"
if [ ! -f "$RDB_FILE" ]; then
echo "❌ File not found: $RDB_FILE"
exit 1
fi
# 解压(如果是 gz)
if [[ "$RDB_FILE" == *.gz ]]; then
TEMP_RDB=$(mktemp --suffix=.rdb)
gunzip -c "$RDB_FILE" > "$TEMP_RDB"
RDB_FILE="$TEMP_RDB"
fi
# 检查 RDB 完整性
if /usr/local/bin/redis-check-rdb "$RDB_FILE" > /dev/null 2>&1; then
echo "✅ RDB integrity OK: $1"
CLEANUP=0
else
echo "❌ RDB file corrupted: $1"
CLEANUP=1
fi
# 清理临时文件
[ -n "$TEMP_RDB" ] && rm -f "$TEMP_RDB"
exit $CLEANUP
验证 AOF 文件
redis-check-aof --nofsync /backup/redis/appendonly.aof
2.3 策略三:校验和(Checksum)监控
生成并验证 SHA256
# 生成校验和
sha256sum /backup/redis/dump-*.rdb.gz > /backup/redis/checksums.sha256
# 验证
sha256sum -c /backup/redis/checksums.sha256
自动化脚本
#!/bin/bash
# monitor_checksum.sh
CHECKSUM_FILE="/backup/redis/checksums.sha256"
NEW_CHECKSUM=$(sha256sum /backup/redis/latest.rdb.gz | awk '{print $1}')
# 检查是否与上次一致(可选)
if [ -f "$CHECKSUM_FILE" ]; then
OLD_CHECKSUM=$(grep latest.rdb.gz "$CHECKSUM_FILE" | awk '{print $1}')
if [ "$NEW_CHECKSUM" != "$OLD_CHECKSUM" ]; then
echo "✅ Backup changed (expected)"
else
echo "⚠️ Backup not updated!"
exit 1
fi
fi
# 更新校验和
sha256sum /backup/redis/*.rdb.gz > "$CHECKSUM_FILE"
2.4 策略四:恢复能力验证(最关键!)
目标:
定期在测试环境恢复备份,验证可用性。
自动化恢复演练脚本
#!/bin/bash
# restore_dry_run.sh
TEST_REDIS_PORT=6380
LATEST_RDB=$(ls -t /backup/redis/dump-*.rdb.gz | head -1)
TEMP_DIR=$(mktemp -d)
echo "🎯 Dry run restore: $LATEST_RDB"
# 1. 解压
gunzip -c "$LATEST_RDB" > "$TEMP_DIR/dump.rdb"
# 2. 启动临时 Redis 实例
redis-server --port $TEST_REDIS_PORT \
--dir "$TEMP_DIR" \
--dbfilename dump.rdb \
--daemonize yes
sleep 5
# 3. 检查是否启动成功
if redis-cli -p $TEST_REDIS_PORT PING | grep -q "PONG"; then
KEY_COUNT=$(redis-cli -p $TEST_REDIS_PORT DBSIZE)
echo "✅ Restore successful. Keys: $KEY_COUNT"
RESTORE_OK=0
else
echo "❌ Restore failed!"
RESTORE_OK=1
fi
# 4. 清理
redis-cli -p $TEST_REDIS_PORT SHUTDOWN
rm -rf "$TEMP_DIR"
exit $RESTORE_OK
📅 建议每周执行一次。
2.5 策略五:备份链一致性检查
目标:
确保 RDB 全量 + AOF 增量时间连续。
#!/bin/bash
# check_backup_chain.sh
RDB_TIME=$(basename $(ls -t /backup/redis/dump-*.rdb.gz | head -1) | cut -d- -f2 | cut -c1-8)
INCREMENTAL_FILES=$(ls /backup/redis/aof_incremental_*.aof.gz | sort)
LAST_RDB_TS=$(date -d "$RDB_TIME" +%s)
for file in $INCREMENTAL_FILES; do
FILE_DATE=$(echo "$file" | grep -oE '[0-9]{8}_[0-9]{6}')
FILE_TS=$(date -d "$FILE_DATE" +%s)
if [ $FILE_TS -lt $LAST_RDB_TS ]; then
echo "❌ Incremental file $file is older than RDB!"
exit 1
fi
done
echo "✅ Backup chain is consistent"
三、日志与审计监控
3.1 记录关键事件
# backup.log
2025-04-05 02:00:00 [INFO] RDB backup completed: /backup/redis/dump-20250405.rdb.gz
2025-04-05 02:00:05 [INFO] SHA256: a1b2c3d...
2025-04-05 02:00:10 [INFO] Uploaded to S3: s3://bucket/redis/dump-20250405.rdb.gz
3.2 使用 Logstash 收集备份日志
input {
file {
path => "/backup/redis/backup.log"
start_position => "beginning"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{LOGLEVEL:level}\] %{GREEDYDATA:msg}" }
}
}
output {
elasticsearch {
hosts => ["http://es:9200"]
index => "backup-audit-%{+YYYY.MM.dd}"
}
}
四、集成主流监控系统
4.1 Prometheus + Grafana
自定义 Exporter(Python)
from prometheus_client import start_http_server, Gauge
import subprocess
import time
backup_exists = Gauge('redis_backup_exists', '1 if backup exists')
backup_integrity = Gauge('redis_backup_integrity', '1 if RDB is valid')
restore_success = Gauge('redis_restore_last_success', 'Timestamp of last successful restore')
def check_backup():
# 检查文件存在
result = subprocess.run(['find', '/backup/redis', '-name', 'dump-*.rdb.gz', '-mmin', '-1440'],
capture_output=True)
backup_exists.set(1 if result.returncode == 0 else 0)
def check_integrity():
latest = subprocess.getoutput('ls -t /backup/redis/dump-*.rdb.gz | head -1')
result = subprocess.run(['/usr/local/bin/redis-check-rdb', latest],
capture_output=True)
backup_integrity.set(1 if result.returncode == 0 else 0)
if __name__ == '__main__':
start_http_server(9101)
while True:
check_backup()
check_integrity()
time.sleep(300) # 每 5 分钟检查
Grafana 仪表盘指标:
redis_backup_exists == 0→ 告警redis_backup_integrity == 0→ 紧急告警- 恢复成功率趋势
4.2 Zabbix / Nagios
使用自定义脚本检查:
# zabbix_agentd.conf
UserParameter=redis.backup.exists,/path/to/check_backup_existence.sh
UserParameter=redis.backup.integrity,/path/to/verify_rdb_integrity.sh /backup/redis/latest.rdb.gz
五、告警策略
| 事件 | 告警级别 | 通知方式 |
|---|---|---|
| 备份未生成 | ⚠️ 警告 | 邮件、企业微信 |
| 文件损坏 | 🔴 紧急 | 邮件、短信、电话 |
| 恢复演练失败 | 🔴 紧急 | 电话、钉钉 |
| 校验和不匹配 | ⚠️ 警告 | 邮件 |
| 备份链断裂 | ⚠️ 警告 | 邮件 |
六、最佳实践总结
| 项目 | 推荐做法 |
|---|---|
| 存在性 | 每小时检查备份是否生成 |
| 完整性 | 每次备份后运行 redis-check-rdb |
| 可恢复性 | 每周执行恢复演练 |
| 自动化 | 所有检查脚本化、定时执行 |
| 文档化 | 记录恢复步骤和负责人 |
| 权限 | 备份文件仅限 root 和备份用户读取 |
七、参考资源
- Redis RDB 校验工具:https://redis.io/docs/management/rdb-check/
- Prometheus 客户端:https://github.com/prometheus/client_python
- 备份监控最佳实践:https://www.cockroachlabs.com/blog/backup-validation/
结语
监控备份完整性,是数据安全的最后一道防线。
通过:
- ✅ 自动化脚本 验证文件存在与完整性
- ✅ 定期恢复演练 验证可用性
- ✅ 集成监控系统 实时告警
你可以确保在灾难发生时,备份真正“拿得出、用得上”。
🔑 记住:The only thing worse than no backup is a broken backup.
2万+

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



