跳轉到內容

rsync 數據同步與增量備份實戰 2026

rsync 數據同步與增量備份

💡 什麼是 rsync? rsync 是一個強大的文件同步工具,它能夠高效地同步文件和目錄,支持增量同步、遠程同步、斷點續傳等功能,是數據備份和遷移的首選工具。

本文將帶你從 0 到 1 掌握:

  • ✅ rsync 基本語法與常用選項
  • ✅ 本地文件同步
  • ✅ 遠程服務器同步(SSH)
  • ✅ 增量備份策略
  • ✅ 斷點續傳與限速
  • ✅ 定時備份配置

一、rsync 基礎

1.1 rsync 工作原理

rsync 使用一種高效的增量算法,只傳輸文件中變化的部分:

┌──────────────┐    計算差異    ┌──────────────┐
│   源文件     │ ─────────────► │   目標文件   │
│   Source    │                │   Target    │
└──────────────┘                └──────────────┘
        │                             │
        │      僅傳輸差異部分          │
        └─────────────────────────────►

1.2 基本語法

bash
# 本地同步
rsync [選項] 源路徑 目標路徑

# 遠程同步(推送到遠程)
rsync [選項] 源路徑 user@remote-host:目標路徑

# 遠程同步(從遠程拉取)
rsync [選項] user@remote-host:源路徑 目標路徑

1.3 常用選項說明

選項說明示例
-a歸檔模式(-rlptgoD 的組合)rsync -a source/ dest/
-v詳細輸出rsync -av source/ dest/
-z壓縮傳輸rsync -az source/ dest/
-P顯示進度 + 斷點續傳rsync -aP source/ dest/
-delete刪除目標中源不存在的文件rsync -av --delete source/ dest/
-exclude排除指定文件rsync -av --exclude='*.log' source/ dest/
-include包含指定文件rsync -av --include='*.txt' source/ dest/
-dry-run模擬運行(不實際傳輸)rsync -av --dry-run source/ dest/
-u僅更新(跳過目標更新時間較新的文件)rsync -avu source/ dest/
-b創建備份文件rsync -avb source/ dest/

二、本地文件同步

2.1 基本同步

bash
# 同步目錄(不包含目錄本身)
rsync -av /path/to/source/ /path/to/dest/

# 同步目錄(包含目錄本身)
rsync -av /path/to/source /path/to/dest/

# 同步單個文件
rsync -av /path/to/source/file.txt /path/to/dest/

# 顯示傳輸進度
rsync -aP /path/to/source/ /path/to/dest/

2.2 增量同步

bash
# 首次同步
rsync -av /path/to/source/ /path/to/dest/

# 增量同步(只傳輸變化的文件)
rsync -av /path/to/source/ /path/to/dest/

# 使用 -u 跳過目標更新時間較新的文件
rsync -avu /path/to/source/ /path/to/dest/

2.3 排除與包含

bash
# 排除指定文件或目錄
rsync -av --exclude='*.log' /path/to/source/ /path/to/dest/
rsync -av --exclude='node_modules/' /path/to/source/ /path/to/dest/
rsync -av --exclude='*.{log,txt}' /path/to/source/ /path/to/dest/

# 排除多個模式
rsync -av \
  --exclude='*.log' \
  --exclude='node_modules/' \
  --exclude='.git/' \
  /path/to/source/ /path/to/dest/

# 使用排除文件
cat > exclude.txt << 'EOF'
*.log
node_modules/
.git/
.DS_Store
EOF
rsync -av --exclude-from='exclude.txt' /path/to/source/ /path/to/dest/

# 包含特定文件,排除其他
rsync -av \
  --include='*.txt' \
  --exclude='*' \
  /path/to/source/ /path/to/dest/

2.4 刪除目標多餘文件

bash
# 刪除目標中源不存在的文件(鏡像同步)
rsync -av --delete /path/to/source/ /path/to/dest/

# 謹慎使用!先模擬運行
rsync -av --delete --dry-run /path/to/source/ /path/to/dest/

三、遠程服務器同步

3.1 通過 SSH 同步

bash
# 推送本地文件到遠程服務器
rsync -avz /path/to/local/ user@remote-host:/path/to/remote/

# 從遠程服務器拉取文件
rsync -avz user@remote-host:/path/to/remote/ /path/to/local/

# 指定 SSH 端口
rsync -avz -e 'ssh -p 2222' /path/to/local/ user@remote-host:/path/to/remote/

# 使用 SSH 密鑰認證
rsync -avz -e 'ssh -i ~/.ssh/my-key' /path/to/local/ user@remote-host:/path/to/remote/

3.2 遠程同步最佳實踐

bash
# 壓縮傳輸(適合慢速網絡)
rsync -avzP /path/to/local/ user@remote-host:/path/to/remote/

# 限制傳輸速度(單位:KB/s)
rsync -avz --bwlimit=1000 /path/to/local/ user@remote-host:/path/to/remote/

# 後臺傳輸
rsync -avz --progress /path/to/local/ user@remote-host:/path/to/remote/ &

# 輸出到日誌文件
rsync -avz /path/to/local/ user@remote-host:/path/to/remote/ > /var/log/rsync.log 2>&1

3.3 多服務器同步

bash
# 同步到多個服務器
servers=("server1.example.com" "server2.example.com" "server3.example.com")
for server in "${servers[@]}"; do
  echo "Syncing to $server..."
  rsync -avz /path/to/source/ user@$server:/path/to/dest/
done

四、增量備份策略

4.1 完整備份 + 增量備份

bash
# 創建完整備份
rsync -av /path/to/source/ /path/to/backup/full/$(date +%Y%m%d)/

# 創建增量備份(硬鏈接)
rsync -av --link-dest=/path/to/backup/full/$(date -d '1 day ago' +%Y%m%d) \
  /path/to/source/ \
  /path/to/backup/incremental/$(date +%Y%m%d)/

4.2 時間點快照備份

bash
# 創建時間點快照
BACKUP_DIR="/path/to/backup"
SOURCE_DIR="/path/to/source"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# 創建快照目錄
mkdir -p "$BACKUP_DIR/snapshots/$TIMESTAMP"

# 使用硬鏈接創建增量快照
rsync -av \
  --link-dest="$BACKUP_DIR/latest" \
  "$SOURCE_DIR/" \
  "$BACKUP_DIR/snapshots/$TIMESTAMP/"

# 更新 latest 鏈接
rm -f "$BACKUP_DIR/latest"
ln -s "$BACKUP_DIR/snapshots/$TIMESTAMP" "$BACKUP_DIR/latest"

4.3 保留指定數量的備份

bash
# 保留最近 7 天的備份
BACKUP_DIR="/path/to/backup/snapshots"
KEEP_DAYS=7

# 刪除舊備份
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$KEEP_DAYS -exec rm -rf {} \;

五、斷點續傳與恢復

5.1 斷點續傳

bash
# 使用 -P 選項啟用斷點續傳
rsync -avzP /path/to/large-file user@remote-host:/path/to/dest/

# 手動斷點續傳(大文件)
rsync -avz --partial --progress /path/to/large-file user@remote-host:/path/to/dest/

# 恢復中斷的傳輸
rsync -avzP --append /path/to/local-file user@remote-host:/path/to/dest/

5.2 傳輸大文件

bash
# 傳輸超大文件
rsync -avz --progress --bwlimit=5000 /path/to/large-file.iso user@remote-host:/path/to/dest/

# 分塊傳輸(配合 split)
split -b 1G /path/to/large-file.iso /path/to/chunks/file-part-
rsync -avz /path/to/chunks/ user@remote-host:/path/to/dest/chunks/

# 在遠程服務器合併
ssh user@remote-host "cat /path/to/dest/chunks/file-part-* > /path/to/dest/large-file.iso"

六、定時備份配置

6.1 使用 cron 定時備份

bash
# 編輯 crontab
crontab -e

# 添加定時任務(每天凌晨 2 點備份)
0 2 * * * /usr/bin/rsync -avz --delete /path/to/source/ /path/to/backup/ > /var/log/rsync-backup.log 2>&1

# 每週日凌晨 3 點完整備份
0 3 * * 0 /usr/bin/rsync -avz /path/to/source/ /path/to/backup/weekly/$(date +%Y%m%d)/

# 每小時增量備份
0 * * * * /usr/bin/rsync -avz /path/to/source/ /path/to/backup/hourly/

6.2 備份腳本示例

bash
#!/bin/bash
# backup.sh - 自動化備份腳本

# 配置
SOURCE_DIR="/var/www/html"
BACKUP_DIR="/backup/web"
REMOTE_SERVER="backup.example.com"
REMOTE_DIR="/backup/web"
LOG_FILE="/var/log/backup.log"

# 創建日誌函數
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}

log "開始備份..."

# 本地備份
if ! rsync -av --delete "$SOURCE_DIR/" "$BACKUP_DIR/local/"; then
  log "本地備份失敗"
  exit 1
fi

log "本地備份完成"

# 遠程備份
if ! rsync -avz --delete "$SOURCE_DIR/" user@"$REMOTE_SERVER":"$REMOTE_DIR/"; then
  log "遠程備份失敗"
  exit 1
fi

log "遠程備份完成"

# 清理舊備份(保留最近 7 天)
find "$BACKUP_DIR/local" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
log "清理舊備份完成"

log "備份完成"

6.3 配置 systemd 服務

bash
# /etc/systemd/system/backup.service
[Unit]
Description=Daily Backup Service
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root

[Install]
WantedBy=multi-user.target
bash
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily Backup Timer

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
bash
# 啟用定時任務
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer

七、實戰應用場景

7.1 場景一:網站數據備份

bash
# 備份網站文件和數據庫
#!/bin/bash

WEB_DIR="/var/www/example.com"
DB_NAME="example_db"
BACKUP_DIR="/backup/example.com"
DATE=$(date +%Y%m%d_%H%M%S)

# 創建備份目錄
mkdir -p "$BACKUP_DIR/$DATE"

# 備份網站文件
rsync -av --delete "$WEB_DIR/" "$BACKUP_DIR/$DATE/files/"

# 備份數據庫
mysqldump -u root -p"$DB_PASSWORD" "$DB_NAME" > "$BACKUP_DIR/$DATE/database.sql"

# 清理 7 天前的備份
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;

7.2 場景二:服務器遷移

bash
# 從舊服務器遷移到新服務器
# 在舊服務器上執行
rsync -avzP \
  --exclude='*.log' \
  --exclude='node_modules/' \
  --exclude='*.pid' \
  /var/www/ \
  user@new-server:/var/www/

# 遷移數據庫
mysqldump -u root -p old_database | ssh user@new-server "mysql -u root -p new_database"

7.3 場景三:NAS 數據同步

bash
# 同步本地文件到 NAS
rsync -avzP \
  --delete \
  --exclude='.DS_Store' \
  --exclude='Thumbs.db' \
  /Users/username/Documents/ \
  user@nas.local:/volume1/backup/Documents/

# 從 NAS 恢復文件
rsync -avzP user@nas.local:/volume1/backup/Documents/ /Users/username/Documents/

7.4 場景四:跨網絡同步

bash
# 通過 SSH 隧道同步
# 先建立隧道
ssh -f -N -L 2222:target-server:22 user@jump-server

# 通過隧道同步
rsync -avz -e 'ssh -p 2222' /path/to/source/ user@localhost:/path/to/dest/

八、rsync 優化

8.1 性能優化

bash
# 使用更快的加密算法
rsync -avz -e 'ssh -c aes128-gcm@openssh.com' /path/to/source/ user@remote:/path/to/dest/

# 禁用壓縮(快速網絡)
rsync -av /path/to/source/ user@remote:/path/to/dest/

# 增加緩衝區大小
rsync -avz --buffer-size=64K /path/to/source/ user@remote:/path/to/dest/

# 使用增量檢查(默認啟用)
rsync -avz --checksum /path/to/source/ user@remote:/path/to/dest/

8.2 並行傳輸

bash
# 使用 rsync 的 --parallel 選項(需要 rsync 3.2.0+)
rsync -avz --parallel=4 /path/to/source/ user@remote:/path/to/dest/

# 或者使用 parallel-rsync
parallel-rsync -h

8.3 配置文件

bash
# ~/.rsyncrc
[defaults]
  verbose = true
  archive = true
  compress = true
  progress = true

[web-backup]
  source = /var/www/
  destination = user@backup-server:/backup/web/
  exclude = *.log, node_modules/, .git/

# 使用配置文件
rsync --config=~/.rsyncrc web-backup

九、常見問題與解決方案

Q1:權限問題

bash
# 保留文件權限
rsync -av /path/to/source/ /path/to/dest/

# 使用 sudo 同步系統文件
rsync -av --rsync-path='sudo rsync' /path/to/source/ user@remote:/path/to/dest/

Q2:符號鏈接問題

bash
# 默認:複製符號鏈接本身
rsync -av /path/to/source/ /path/to/dest/

# 複製符號鏈接指向的文件
rsync -avL /path/to/source/ /path/to/dest/

# 保留硬鏈接
rsync -avH /path/to/source/ /path/to/dest/

Q3:隱藏文件問題

bash
# 默認:不復制以 . 開頭的文件
rsync -av /path/to/source/ /path/to/dest/

# 複製隱藏文件
rsync -av /path/to/source/. /path/to/dest/

Q4:傳輸中斷

bash
# 使用 -P 選項支持斷點續傳
rsync -avzP /path/to/source/ user@remote:/path/to/dest/

# 恢復中斷的傳輸
rsync -avz --partial /path/to/source/ user@remote:/path/to/dest/

Q5:帶寬佔用過高

bash
# 限制傳輸速度
rsync -avz --bwlimit=1000 /path/to/source/ user@remote:/path/to/dest/

# 在特定時間同步(使用 cron)
# 凌晨 2 點到 6 點不受限制
0 2-6 * * * rsync -avz /path/to/source/ user@remote:/path/to/dest/
# 其他時間限速
0 7-23 * * * rsync -avz --bwlimit=500 /path/to/source/ user@remote:/path/to/dest/

十、完整備份方案

10.1 企業級備份腳本

bash
#!/bin/bash
# enterprise-backup.sh - 企業級備份方案

# 配置
SOURCE_DIRS=(
  "/var/www/html"
  "/etc"
  "/home"
)
BACKUP_SERVER="backup.example.com"
BACKUP_DIR="/backup/production"
RETENTION_DAYS=30
LOG_FILE="/var/log/enterprise-backup.log"

# 函數:日誌記錄
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}

# 函數:發送告警
send_alert() {
  echo "Backup failed: $1" | mail -s "Backup Alert" admin@example.com
}

log "========== 開始備份 =========="

# 檢查遠程服務器
if ! ping -c 1 "$BACKUP_SERVER" > /dev/null 2>&1; then
  log "遠程服務器不可達"
  send_alert "Remote server $BACKUP_SERVER is unreachable"
  exit 1
fi

# 同步每個目錄
for SOURCE in "${SOURCE_DIRS[@]}"; do
  DIR_NAME=$(basename "$SOURCE")
  log "同步 $SOURCE..."
  
  if ! rsync -avz --delete \
    --exclude='*.log' \
    --exclude='*.pid' \
    --exclude='*.tmp' \
    "$SOURCE/" \
    user@"$BACKUP_SERVER":"$BACKUP_DIR/$DIR_NAME/"; then
    
    log "$SOURCE 同步失敗"
    send_alert "Failed to sync $SOURCE"
  else
    log "$SOURCE 同步成功"
  fi
done

# 清理舊備份
log "清理 $RETENTION_DAYS 天前的備份..."
ssh user@"$BACKUP_SERVER" "find $BACKUP_DIR -type f -mtime +$RETENTION_DAYS -delete"

log "========== 備份完成 =========="

10.2 異地災備方案

bash
# 主備份:本地 NAS
rsync -avz /path/to/data/ user@nas.local:/volume1/backup/

# 異地備份:遠程服務器
rsync -avz /path/to/data/ user@remote-backup.example.com:/backup/

# 加密備份
rsync -avz -e 'ssh -c aes256-gcm@openssh.com' /path/to/data/ user@secure-server:/encrypted-backup/

# 定期驗證備份完整性
rsync -avz --checksum /path/to/data/ user@backup-server:/backup/ > /dev/null || send_alert "Backup verification failed"

結語

rsync 是一個功能強大的數據同步工具,支持高效的增量同步、遠程傳輸、斷點續傳等功能,是數據備份和遷移的首選工具。通過本文的學習,你已經掌握了:

  1. 基本同步:本地和遠程文件同步
  2. 增量備份:只傳輸變化的文件
  3. 排除與包含:靈活控制同步內容
  4. 定時備份:使用 cron 和 systemd 自動化
  5. 斷點續傳:大文件傳輸恢復
  6. 性能優化:提高同步效率

推薦閱讀:


🚀 提示: 在生產環境中,建議定期驗證備份完整性,採用異地備份策略,並配置監控告警機制。


延伸阅读

免责声明

本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。

最後更新於: