本文目录导读:

编写监控数据灾备演练脚本时,需要根据具体的监控系统(如Prometheus、Zabbix、Grafana、ELK等)以及底层数据存储(如TSDB、MySQL、Elasticsearch、对象存储等)来确定具体逻辑。
以下是一个通用、模块化的灾备演练脚本框架,适用于Prometheus + Thanos / VictoriaMetrics 或 Ceph / MinIO 对象存储 的场景,你可以根据实际环境修改其中的变量和命令。
核心要点
灾备演练脚本通常需要覆盖以下步骤:
- 环境准备:记录当前数据状态(快照、备份文件)。
- 灾难模拟:停止主服务、断开网络、模拟数据损坏。
- 恢复执行:从备份中恢复数据到备用环境。
- 数据校验:对比恢复后的数据与备份前的记录(关键步骤)。
- 回切/清理:恢复生产环境,清理测试数据。
示例脚本:Prometheus + Thanos 存储到 S3 的灾备演练
#!/bin/bash
# ====================================================
# 监控数据灾备演练脚本(Prometheus + Thanos + S3)
# 用途:验证从S3对象存储恢复监控数据的完整性
# 警告:请勿在生产环境未授权下运行!
# ====================================================
set -euo pipefail
# ---------- 配置变量(请根据实际环境修改)----------
# S3 配置
S3_BUCKET="my-monitoring-backup"
S3_ENDPOINT="https://s3.amazonaws.com"
S3_REGION="us-east-1"
# Thanos 配置
THANOS_STORE_ADDR="thanos-store:10901"
THANOS_QUERIER_ADDR="thanos-querier:9090"
# 本地临时恢复目录
RESTORE_DIR="/tmp/monitor_restore_$(date +%s)"
# 备份文件列表(演练前从备份清单获取)
BACKUP_MANIFEST="/tmp/backup_manifest.txt"
# 时间范围(过去1小时,仅用于快速验证)
QUERY_START="-1h"
QUERY_END="now"
# ---------- 函数定义 ----------
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
pre_checks() {
log "=== 1. 环境预检 ==="
# 检查必要工具
command -v aws >/dev/null 2>&1 || { log "需要安装 aws-cli"; exit 1; }
command -v thanos >/dev/null 2>&1 || { log "需要安装 thanos 工具"; exit 1; }
command -v promtool >/dev/null 2>&1 || { log "需要安装 promtool"; exit 1; }
# 检查S3连通性
aws s3 ls "s3://${S3_BUCKET}" --endpoint "${S3_ENDPOINT}" --region "${S3_REGION}" > /dev/null 2>&1 || {
log "无法访问S3桶,请检查配置或网络"; exit 1
}
log "环境预检通过"
}
simulate_disaster() {
log "=== 2. 模拟灾难:删除本地监控数据 ==="
# 注意:此步骤仅应在测试实例上执行,确保不会影响真实数据
if [ "${DISASTER_MODE}" == "true" ]; then
log "正在停止本地Prometheus..."
systemctl stop prometheus || true
log "清空本地数据目录(示例:/data/prometheus)..."
rm -rf /data/prometheus/*
log "灾难模拟完成"
else
log "跳过灾难模拟(仅做恢复验证)"
fi
}
restore_from_backup() {
log "=== 3. 从S3备份恢复数据 ==="
# 创建恢复目录
mkdir -p "${RESTORE_DIR}"
# 从S3下载最近的备份文件(假设备份为 .tar.gz 格式)
# 此处模拟:下载最新的备份文件
LATEST_BACKUP=$(aws s3 ls "s3://${S3_BUCKET}/backups/" --endpoint "${S3_ENDPOINT}" \
--region "${S3_REGION}" --recursive | tail -1 | awk '{print $4}')
if [ -z "${LATEST_BACKUP}" ]; then
log "未找到备份文件,请检查S3路径"
exit 1
fi
log "发现最新备份: ${LATEST_BACKUP}"
aws s3 cp "s3://${S3_BUCKET}/${LATEST_BACKUP}" "${RESTORE_DIR}/backup.tar.gz" \
--endpoint "${S3_ENDPOINT}" --region "${S3_REGION}"
log "解压备份到恢复目录..."
tar -xzf "${RESTORE_DIR}/backup.tar.gz" -C "${RESTORE_DIR}"
# 使用thanso工具验证数据完整性(示例)
log "使用 thanos tools check 验证数据块..."
# thanos tools check --dir "${RESTORE_DIR}/prometheus-data" # 假设解压后为TSDB格式
log "数据恢复完成"
}
validate_data() {
log "=== 4. 数据完整性校验 ==="
# 4.1 启动临时Thanos存储组件(使用恢复的数据)
log "启动临时Thanos Store(隔离环境)..."
# 生产环境不应直接使用恢复数据启动服务,此处仅为演示
# 实际应搭建隔离的thanos sidecar/store
# 4.2 使用PromQL对比关键指标
# 通过 thanos querier 查询过去1小时的数据点数
METRIC_NAME="up"
BEFORE_RECOVERY_COUNT=$(promtool query instant \
--server="${THANOS_QUERIER_ADDR}" \
"count(${METRIC_NAME})" | jq '.data.result[0].value[1]')
# 假设演练脚本在恢复前记录了基准值(此处简化)
log "当前指标 ${METRIC_NAME} 的数量: ${BEFORE_RECOVERY_COUNT}"
# 更严谨的做法:对关键业务指标进行采样对比
# 对比恢复前后的TSDB块索引
# thanos tools inspect tsdb --dir "${RESTORE_DIR}/prometheus-data" > /tmp/restore_inspect.txt
# 计算数据量
BACKUP_SIZE=$(du -sh "${RESTORE_DIR}" | awk '{print $1}')
log "恢复数据总大小: ${BACKUP_SIZE}"
# 根据实际业务定义通过标准
if [ "${BEFORE_RECOVERY_COUNT}" -gt 0 ]; then
log "校验通过:数据可查询可用"
else
log "校验警告:数据查询返回空,请进一步检查"
fi
}
cleanup() {
log "=== 5. 清理现场 ==="
if [ "${CLEANUP}" == "true" ]; then
log "清理临时恢复目录: ${RESTORE_DIR}"
rm -rf "${RESTORE_DIR}"
log "清理完成"
else
log "保留恢复目录以便人工审查: ${RESTORE_DIR}"
fi
}
# ---------- 主流程 ----------
main() {
log "========== 监控数据灾备演练开始 =========="
pre_checks
# 危险操作需要确认
if [ "${DISASTER_MODE}" == "true" ]; then
log "警告:即将模拟数据删除!请在测试环境执行。"
read -p "确认继续? (yes/no): " confirmation
if [ "$confirmation" != "yes" ]; then
log "用户取消演练"
exit 0
fi
fi
simulate_disaster
restore_from_backup
validate_data
cleanup
log "========== 演练脚本执行完成 =========="
}
# ---------- 参数解析 ----------
# 运行方式:
# ./monitor_dr_drill.sh # 跳过灾难模拟只做恢复验证
# ./monitor_dr_drill.sh --disaster # 包含灾难模拟(删除本地数据)
# ./monitor_dr_drill.sh --no-cleanup # 保留恢复数据
DISASTER_MODE=false
CLEANUP=true
while [[ $# -gt 0 ]]; do
case $1 in
--disaster)
DISASTER_MODE=true
shift
;;
--no-cleanup)
CLEANUP=false
shift
;;
*)
echo "未知参数: $1"
exit 1
;;
esac
done
main
针对不同监控系统的关键差异
| 监控系统 | 数据存储 | 备份方式 | 恢复验证关键点 |
|---|---|---|---|
| Prometheus | 本地TSDB | 快照 (snapshot API) + 对象存储 | 检查时间序列连续性、压缩块完整性 |
| Zabbix | MySQL / PostgreSQL | 数据库逻辑备份 (mysqldump) | 检查最近24小时告警、主机最新数据 |
| ELK (Elasticsearch) | Elasticsearch 索引 | 快照到S3 (snapshot API) | 检查最新日志写入、聚合查询结果 |
| Grafana | Grafana SQLite / MySQL | 文件备份 + 数据库备份 | 检查Dashboard列表、告警规则、数据源连接 |
| 夜莺 (Nightingale) | MySQL + Redis | 数据库Dump + n9e数据导出 | 检查告警规则、监控大盘、历史数据查询 |
更安全的演练方式
如果无法直接删除数据,可以采用 “沙箱测试” 方法:
- 备份环境隔离:在另一台机器上部署相同架构的监控系统。
- 数据注入:将备份数据挂载到沙箱环境。
- 查询验证:通过测试仪表盘查询特定时间范围的数据。
- 指标对比:使用自动化脚本对比主环境和沙箱环境的关键指标(差值 ≤ 1% 为通过)。
脚本中的关键安全建议
- 绝不自动化删除:脚本中删除数据的逻辑(
simulate_disaster)应始终被参数控制,并在交互模式下运行。 - 记录演练报告:自动记录每个步骤的执行时间、文件大小、校验结果,输出到报告文件。
- 资源限制:恢复数据时限制带宽(
aws s3 cp --cli-read-timeout),防止影响其他业务。 - 权限最小化:用于灾备演练的密钥应只有读取备份和写入沙箱环境的权限。