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