海外服务器数据备份完整策略:rsync + Rclone + 对象存储三层备份方案实操

海外服务器数据备份完整策略:rsync + Rclone + 对象存储三层备份方案实操

数据无价,备份无悔。硬盘故障、误操作、勒索软件攻击——这些风险在没有备份的情况下都是灾难性的。本文为香港 VPS 设计一套三层备份架构:本地快照 + 异地同步 + 对象存储,覆盖从分钟级到月级的完整数据保护。


一、三层备份架构设计

备份层工具存储位置保留周期主要防护
第一层:本地增量rsync本机另一分区7天误操作、文件损坏
第二层:异地同步Rclone另一台 VPS14天机房故障、硬件损坏
第三层:云端归档RcloneCloudflare R2 / S390天勒索软件、完全丢失

二、第一层:rsync 本地增量备份

<code">mkdir -p /backup/{daily,weekly,mysql,configs}

# 创建主备份脚本
cat > /usr/local/bin/backup-local.sh << 'SCRIPT' #!/bin/bash set -euo pipefail DATE=$(date +%Y%m%d) BACKUP_ROOT="/backup" LOG="/var/log/backup.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a $LOG; } # ── 1. 网站文件增量备份 ── log "开始备份网站文件..." rsync -avz --delete \ --exclude='*.log' \ --exclude='*.tmp' \ --exclude='wp-content/cache/' \ /var/www/ \ $BACKUP_ROOT/daily/www-$DATE/ log "网站文件备份完成" # ── 2. MySQL 全量备份 ── log "开始备份 MySQL..." mkdir -p $BACKUP_ROOT/mysql # 逐库备份(方便单库恢复) mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SHOW DATABASES;" \ | grep -Ev "Database|information_schema|performance_schema|sys" \ | while read db; do mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" \ --single-transaction \ --routines \ --triggers \ "$db" | gzip > $BACKUP_ROOT/mysql/${db}_${DATE}.sql.gz
    log "已备份数据库: $db"
done

# ── 3. 配置文件备份 ──
log "备份配置文件..."
tar -czf $BACKUP_ROOT/configs/configs-$DATE.tar.gz \
  /etc/nginx \
  /etc/mysql \
  /etc/php \
  /etc/letsencrypt \
  /etc/crontab \
  /opt/monitoring 2>/dev/null || true

# ── 4. 清理 7 天前的旧备份 ──
find $BACKUP_ROOT/daily -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +
find $BACKUP_ROOT/mysql -name "*.sql.gz" -mtime +7 -delete
find $BACKUP_ROOT/configs -name "*.tar.gz" -mtime +7 -delete

log "本地备份完成 ✓"
SCRIPT

chmod +x /usr/local/bin/backup-local.sh

三、第二层:Rclone 安装与配置

<code"># 安装 Rclone
curl https://rclone.org/install.sh | bash
rclone version

配置 Cloudflare R2(推荐:出口流量免费)

<code"># 交互式配置(rclone config)
# 或直接写入配置文件
mkdir -p ~/.config/rclone
cat > ~/.config/rclone/rclone.conf << 'EOF'
[r2]
type = s3
provider = Cloudflare
access_key_id = YOUR_R2_ACCESS_KEY
secret_access_key = YOUR_R2_SECRET_KEY
endpoint = https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com
acl = private

[backup-vps2]
type = sftp
host = 第二台VPS的IP
user = root
key_file = /root/.ssh/backup_key   # 专用备份密钥
EOF

# 测试连接
rclone ls r2:
rclone ls backup-vps2:

Rclone 同步脚本

<code">cat > /usr/local/bin/backup-remote.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail
LOG="/var/log/backup-remote.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a $LOG; }

# ── 同步到备用 VPS ──
log "同步备份到异地 VPS..."
rclone sync /backup/ backup-vps2:/backup/hk-vps-01/ \
  --transfers 4 \
  --checkers 8 \
  --log-file=$LOG \
  --log-level INFO
log "异地同步完成 ✓"

# ── 归档到 Cloudflare R2 ──
log "归档到 Cloudflare R2..."
# MySQL 备份:每天同步
rclone sync /backup/mysql/ r2:your-backup-bucket/mysql/ \
  --transfers 4 \
  --s3-chunk-size 64M \
  --log-file=$LOG

# 网站文件:只同步最新的(节省存储成本)
LATEST=$(ls -dt /backup/daily/www-* | head -1)
rclone sync "$LATEST" r2:your-backup-bucket/www-latest/ \
  --transfers 8

log "R2 归档完成 ✓"
SCRIPT

chmod +x /usr/local/bin/backup-remote.sh

四、自动化 Crontab 调度

<code"># 编辑 crontab
crontab -e

# 添加以下调度规则
# ────────────────────────────────────────
# 每天凌晨 2:00 执行本地备份
0 2 * * * MYSQL_ROOT_PASSWORD="yourpassword" /usr/local/bin/backup-local.sh

# 每天凌晨 3:30 执行远程同步(本地备份完成后)
30 3 * * * /usr/local/bin/backup-remote.sh

# 每周日凌晨 4:00 执行完整性校验
0 4 * * 0 /usr/local/bin/backup-verify.sh

# ────────────────────────────────────────

五、备份完整性验证脚本

<code">cat > /usr/local/bin/backup-verify.sh << 'SCRIPT' #!/bin/bash LOG="/var/log/backup-verify.log" ERRORS=0 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a $LOG; } # 1. 检查本地备份目录是否存在当天备份 TODAY=$(date +%Y%m%d) if [ ! -d "/backup/daily/www-$TODAY" ]; then log "❌ 错误:当天网站备份不存在" ERRORS=$((ERRORS+1)) fi # 2. 验证 MySQL 备份文件可解压 for gz in /backup/mysql/*_${TODAY}.sql.gz; do if ! gzip -t "$gz" 2>/dev/null; then
        log "❌ 错误:SQL 备份文件损坏: $gz"
        ERRORS=$((ERRORS+1))
    else
        log "✓ SQL 备份完整: $gz"
    fi
done

# 3. 检查 R2 远端文件数量
REMOTE_COUNT=$(rclone ls r2:your-backup-bucket/mysql/ | wc -l)
LOCAL_COUNT=$(ls /backup/mysql/ | wc -l)
if [ "$REMOTE_COUNT" -lt "$LOCAL_COUNT" ]; then
    log "⚠️  警告:R2 备份数量($REMOTE_COUNT)少于本地($LOCAL_COUNT)"
    ERRORS=$((ERRORS+1))
fi

# 4. 发送校验报告
if [ "$ERRORS" -gt 0 ]; then
    log "校验完成:发现 $ERRORS 个问题,请检查"
    # 发送告警邮件(需配置 mailutils)
    echo "备份校验失败,发现 $ERRORS 个问题,请立即检查 $LOG" \
      | mail -s "🚨 备份告警" admin@yourdomain.com
else
    log "✅ 备份校验全部通过"
fi
SCRIPT

chmod +x /usr/local/bin/backup-verify.sh

六、快速恢复操作手册

从本地备份恢复网站文件

<code"># 列出可用备份
ls /backup/daily/

# 恢复到指定日期(替换现有文件)
rsync -avz /backup/daily/www-20260601/ /var/www/ --delete

恢复 MySQL 数据库

<code"># 从压缩备份恢复单个数据库
gunzip < /backup/mysql/mydb_20260601.sql.gz | mysql -uroot -p mydb

# 如需从 R2 下载备份
rclone copy r2:your-backup-bucket/mysql/mydb_20260601.sql.gz /tmp/
gunzip < /tmp/mydb_20260601.sql.gz | mysql -uroot -p mydb

七、存储成本估算

存储方案月存储成本(50G数据)出口流量费
Cloudflare R2$0.75($0.015/GB)免费 ✅
AWS S3$1.15($0.023/GB)$0.09/GB ❌
阿里云 OSS¥0.6(¥0.12/GB)¥0.25/GB

推荐:Cloudflare R2 对中小规模备份最经济,无出口流量费,从 VPS 上传备份、下载恢复均不计费。

八、总结

三层备份策略(本地 rsync → 异地 VPS → Cloudflare R2)为香港 VPS 数据提供了全面保护,从日常误操作到极端的机房故障均有备案。建议所有生产环境 VPS 在上线第一天就配置好备份,而不是等到数据丢失后才后悔。

Telegram