跳转到内容

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 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。