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

💡 什麼是 rsync? rsync 是一個強大的文件同步工具,它能夠高效地同步文件和目錄,支持增量同步、遠程同步、斷點續傳等功能,是數據備份和遷移的首選工具。
本文將帶你從 0 到 1 掌握:
- ✅ rsync 基本語法與常用選項
- ✅ 本地文件同步
- ✅ 遠程服務器同步(SSH)
- ✅ 增量備份策略
- ✅ 斷點續傳與限速
- ✅ 定時備份配置
一、rsync 基礎
1.1 rsync 工作原理
rsync 使用一種高效的增量算法,只傳輸文件中變化的部分:
┌──────────────┐ 計算差異 ┌──────────────┐
│ 源文件 │ ─────────────► │ 目標文件 │
│ Source │ │ Target │
└──────────────┘ └──────────────┘
│ │
│ 僅傳輸差異部分 │
└─────────────────────────────►1.2 基本語法
# 本地同步
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 基本同步
# 同步目錄(不包含目錄本身)
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 增量同步
# 首次同步
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 排除與包含
# 排除指定文件或目錄
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 刪除目標多餘文件
# 刪除目標中源不存在的文件(鏡像同步)
rsync -av --delete /path/to/source/ /path/to/dest/
# 謹慎使用!先模擬運行
rsync -av --delete --dry-run /path/to/source/ /path/to/dest/三、遠程服務器同步
3.1 通過 SSH 同步
# 推送本地文件到遠程服務器
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 遠程同步最佳實踐
# 壓縮傳輸(適合慢速網絡)
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>&13.3 多服務器同步
# 同步到多個服務器
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 完整備份 + 增量備份
# 創建完整備份
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 時間點快照備份
# 創建時間點快照
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 保留指定數量的備份
# 保留最近 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 斷點續傳
# 使用 -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 傳輸大文件
# 傳輸超大文件
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 定時備份
# 編輯 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 備份腳本示例
#!/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 服務
# /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# /etc/systemd/system/backup.timer
[Unit]
Description=Daily Backup Timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target# 啟用定時任務
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer七、實戰應用場景
7.1 場景一:網站數據備份
# 備份網站文件和數據庫
#!/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 場景二:服務器遷移
# 從舊服務器遷移到新服務器
# 在舊服務器上執行
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 數據同步
# 同步本地文件到 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 場景四:跨網絡同步
# 通過 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 性能優化
# 使用更快的加密算法
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 並行傳輸
# 使用 rsync 的 --parallel 選項(需要 rsync 3.2.0+)
rsync -avz --parallel=4 /path/to/source/ user@remote:/path/to/dest/
# 或者使用 parallel-rsync
parallel-rsync -h8.3 配置文件
# ~/.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:權限問題
# 保留文件權限
rsync -av /path/to/source/ /path/to/dest/
# 使用 sudo 同步系統文件
rsync -av --rsync-path='sudo rsync' /path/to/source/ user@remote:/path/to/dest/Q2:符號鏈接問題
# 默認:複製符號鏈接本身
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:隱藏文件問題
# 默認:不復制以 . 開頭的文件
rsync -av /path/to/source/ /path/to/dest/
# 複製隱藏文件
rsync -av /path/to/source/. /path/to/dest/Q4:傳輸中斷
# 使用 -P 選項支持斷點續傳
rsync -avzP /path/to/source/ user@remote:/path/to/dest/
# 恢復中斷的傳輸
rsync -avz --partial /path/to/source/ user@remote:/path/to/dest/Q5:帶寬佔用過高
# 限制傳輸速度
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 企業級備份腳本
#!/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 異地災備方案
# 主備份:本地 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 是一個功能強大的數據同步工具,支持高效的增量同步、遠程傳輸、斷點續傳等功能,是數據備份和遷移的首選工具。通過本文的學習,你已經掌握了:
- 基本同步:本地和遠程文件同步
- 增量備份:只傳輸變化的文件
- 排除與包含:靈活控制同步內容
- 定時備份:使用 cron 和 systemd 自動化
- 斷點續傳:大文件傳輸恢復
- 性能優化:提高同步效率
推薦閱讀:
🚀 提示: 在生產環境中,建議定期驗證備份完整性,採用異地備份策略,並配置監控告警機制。
延伸阅读
免责声明
本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。