rsync 文件同步与备份完全指南

本文最后更新于 1 分钟前,文中所描述的信息可能已发生改变。

rsync(remote synchronize)是一个功能强大的文件同步和传输工具,广泛应用于数据备份、文件镜像和远程同步等场景。它采用增量传输算法,只传输文件的差异部分,大大提高了传输效率。本文将详细介绍 rsync 的使用方法、高级功能和实际应用场景。

rsync 基础概念

rsync 是一个开源的快速、多功能的文件复制工具,可以在本地和远程系统之间同步文件和目录。它的主要特点包括:

  • 增量传输:只传输发生变化的文件部分
  • 保持文件属性:可保持文件的权限、时间戳、所有者等属性
  • 压缩传输:支持数据压缩以减少网络带宽使用
  • 断点续传:支持传输中断后的恢复
  • 灵活的过滤:支持包含和排除文件的复杂规则
  • 多种传输方式:支持本地、SSH、rsync daemon 等多种传输方式

安装 rsync

Ubuntu/Debian 系统

bash
sudo apt update
sudo apt install rsync

CentOS/RHEL 系统

bash
sudo yum install rsync
# 或在较新版本中使用
sudo dnf install rsync

macOS

bash
# 使用 Homebrew
brew install rsync

# 或使用 MacPorts
sudo port install rsync

验证安装

bash
rsync --version

rsync 基本语法

rsync 的基本语法格式为:

bash
rsync [选项] 源路径 目标路径

常用选项说明

  • -a, --archive:归档模式,等价于 -rlptgoD
  • -r, --recursive:递归处理子目录
  • -l, --links:保持符号链接
  • -p, --perms:保持文件权限
  • -t, --times:保持文件时间戳
  • -g, --group:保持文件所属组
  • -o, --owner:保持文件所有者
  • -D:等价于 --devices --specials
  • -v, --verbose:详细输出
  • -z, --compress:传输时压缩数据
  • -h, --human-readable:以人类可读的格式输出
  • --progress:显示传输进度
  • -n, --dry-run:试运行,不实际传输文件
  • --delete:删除目标目录中源目录没有的文件
  • --exclude:排除指定的文件或目录
  • --include:包含指定的文件或目录

本地文件同步

基本复制

bash
# 复制文件
rsync -av source.txt destination.txt

# 复制目录
rsync -av /path/to/source/ /path/to/destination/

注意:源路径末尾的斜杠很重要:

  • source/:复制 source 目录的内容到目标目录
  • source:复制 source 目录本身到目标目录

同步示例

bash
# 将 /home/user/documents/ 同步到 /backup/documents/
rsync -av --progress /home/user/documents/ /backup/documents/

# 同步并删除目标目录中多余的文件
rsync -av --delete /home/user/documents/ /backup/documents/

# 试运行,查看将要执行的操作
rsync -av --dry-run --delete /home/user/documents/ /backup/documents/

排除特定文件

bash
# 排除特定文件类型
rsync -av --exclude='*.tmp' --exclude='*.log' /source/ /destination/

# 排除特定目录
rsync -av --exclude='node_modules' --exclude='.git' /project/ /backup/

# 使用排除文件
echo "*.tmp" > exclude.txt
echo "*.log" >> exclude.txt
rsync -av --exclude-from=exclude.txt /source/ /destination/

远程文件同步

使用 SSH 传输

rsync 可以通过 SSH 协议进行安全的远程传输:

bash
# 从本地同步到远程服务器
rsync -av -e ssh /local/path/ user@remote-host:/remote/path/

# 从远程服务器同步到本地
rsync -av -e ssh user@remote-host:/remote/path/ /local/path/

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

# 使用 SSH 密钥
rsync -av -e "ssh -i ~/.ssh/id_rsa" /local/path/ user@remote-host:/remote/path/

SSH 配置优化

为了简化 rsync 命令,可以在 ~/.ssh/config 中配置 SSH 连接:

Host backup-server
    HostName 192.168.1.100
    User backup
    Port 22
    IdentityFile ~/.ssh/backup_key
    Compression yes

然后可以简化 rsync 命令:

bash
rsync -av /local/path/ backup-server:/remote/path/

使用 rsync daemon

rsync daemon 提供了专门的 rsync 服务,通常运行在 873 端口:

bash
# 连接到 rsync daemon
rsync -av rsync://user@remote-host/module-name/ /local/path/

# 指定端口
rsync -av --port=873 rsync://user@remote-host/module-name/ /local/path/

高级功能和选项

带宽限制

bash
# 限制传输速度为 1000 KB/s
rsync -av --bwlimit=1000 /source/ /destination/

断点续传

rsync 支持断点续传,当传输中断时可以继续:

bash
# 使用 --partial 选项保留部分传输的文件
rsync -av --partial --progress /source/ user@remote:/destination/

# 使用 --partial-dir 指定部分文件存储目录
rsync -av --partial-dir=.rsync-partial /source/ user@remote:/destination/

保持硬链接

bash
# 保持硬链接
rsync -avH /source/ /destination/

稀疏文件处理

bash
# 高效处理稀疏文件
rsync -avS /source/ /destination/

时间戳比较

bash
# 只传输修改时间较新的文件
rsync -avu /source/ /destination/

# 使用校验和而不是时间戳和大小来判断文件是否需要传输
rsync -avc /source/ /destination/

实际应用场景

1. 数据备份脚本

创建一个自动备份脚本:

bash
#!/bin/bash

# 备份配置
SOURCE_DIR="/home/user/important-data"
BACKUP_DIR="/backup/daily"
REMOTE_HOST="backup-server"
REMOTE_PATH="/backups/$(hostname)"
LOG_FILE="/var/log/backup.log"

# 创建日期标记的备份目录
DATE=$(date +%Y-%m-%d)
BACKUP_PATH="$BACKUP_DIR/$DATE"

# 本地备份
echo "$(date): Starting local backup..." >> $LOG_FILE
rsync -av --delete --link-dest="$BACKUP_DIR/latest" \
    "$SOURCE_DIR/" "$BACKUP_PATH/" >> $LOG_FILE 2>&1

# 更新最新备份链接
rm -f "$BACKUP_DIR/latest"
ln -s "$DATE" "$BACKUP_DIR/latest"

# 远程备份
echo "$(date): Starting remote backup..." >> $LOG_FILE
rsync -av --delete -e ssh "$BACKUP_PATH/" \
    "$REMOTE_HOST:$REMOTE_PATH/$DATE/" >> $LOG_FILE 2>&1

echo "$(date): Backup completed." >> $LOG_FILE

2. 网站部署脚本

bash
#!/bin/bash

# 部署配置
LOCAL_BUILD_DIR="./dist"
REMOTE_HOST="web-server"
REMOTE_PATH="/var/www/html"
EXCLUDE_FILE="deploy-exclude.txt"

# 创建排除文件
cat > $EXCLUDE_FILE << EOF
.git/
.gitignore
node_modules/
*.log
.env
EOF

# 部署到生产服务器
echo "Deploying to production server..."
rsync -av --delete --progress \
    --exclude-from="$EXCLUDE_FILE" \
    "$LOCAL_BUILD_DIR/" "$REMOTE_HOST:$REMOTE_PATH/"

# 清理
rm -f $EXCLUDE_FILE

echo "Deployment completed."

3. 镜像同步

bash
#!/bin/bash

# 镜像两个目录,保持完全同步
rsync -av --delete --progress \
    /primary/data/ /mirror/data/

# 双向同步(需要小心使用)
# 注意:双向同步可能导致数据冲突,建议使用专门的双向同步工具

4. 增量备份系统

bash
#!/bin/bash

BACKUP_ROOT="/backups"
SOURCE="/home/user/data"

# 创建基于硬链接的增量备份
CURRENT_BACKUP="$BACKUP_ROOT/$(date +%Y-%m-%d_%H-%M-%S)"
LATEST_BACKUP="$BACKUP_ROOT/latest"

# 如果存在最新备份,使用硬链接
if [ -d "$LATEST_BACKUP" ]; then
    rsync -av --delete --link-dest="$LATEST_BACKUP" \
        "$SOURCE/" "$CURRENT_BACKUP/"
else
    rsync -av "$SOURCE/" "$CURRENT_BACKUP/"
fi

# 更新最新备份链接
rm -f "$LATEST_BACKUP"
ln -s "$(basename "$CURRENT_BACKUP")" "$LATEST_BACKUP"

性能优化

网络优化

bash
# 启用压缩
rsync -avz /source/ user@remote:/destination/

# 调整压缩级别(1-9,默认6)
rsync -av --compress-level=9 /source/ user@remote:/destination/

# 使用多线程(需要较新版本的 rsync)
rsync -av --multi-threaded /source/ user@remote:/destination/

磁盘 I/O 优化

bash
# 减少磁盘写入
rsync -av --inplace /source/ /destination/

# 使用内存缓冲
rsync -av --whole-file /source/ /destination/

SSH 连接优化

~/.ssh/config 中添加:

Host *
    Compression yes
    CompressionLevel 6
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p
    ControlPersist 10m

监控和日志

详细日志记录

bash
# 记录详细的传输信息
rsync -av --progress --stats \
    --log-file=/var/log/rsync.log \
    /source/ /destination/

传输统计

bash
# 显示传输统计信息
rsync -av --stats /source/ /destination/

监控脚本

bash
#!/bin/bash

# 监控 rsync 传输进度
LOG_FILE="/tmp/rsync_progress.log"

# 在后台运行 rsync
rsync -av --progress /large/source/ /destination/ > $LOG_FILE 2>&1 &
RSYNC_PID=$!

# 监控进度
while kill -0 $RSYNC_PID 2>/dev/null; do
    if [ -f $LOG_FILE ]; then
        # 提取最新的进度信息
        tail -n 1 $LOG_FILE | grep -o '[0-9]\+%'
    fi
    sleep 5
done

echo "Transfer completed!"

故障排查

常见问题及解决方案

1. 权限问题

bash
# 确保目标目录有写权限
chmod 755 /destination/

# 使用 sudo 权限
sudo rsync -av /source/ /destination/

2. SSH 连接问题

bash
# 测试 SSH 连接
ssh user@remote-host "echo 'SSH connection works'"

# 详细的 SSH 调试信息
rsync -av -e "ssh -vvv" /source/ user@remote:/destination/

3. 磁盘空间不足

bash
# 检查磁盘空间
df -h /destination/

# 使用 --max-size 限制文件大小
rsync -av --max-size=100M /source/ /destination/

4. 传输中断恢复

bash
# 使用 --partial 和 --append-verify 选项
rsync -av --partial --append-verify /source/ user@remote:/destination/

调试选项

bash
# 详细输出
rsync -avvv /source/ /destination/

# 试运行模式
rsync -av --dry-run /source/ /destination/

# 显示传输的每个文件
rsync -av --itemize-changes /source/ /destination/

安全考虑

1. 使用 SSH 密钥认证

bash
# 生成 SSH 密钥对
ssh-keygen -t rsa -b 4096 -f ~/.ssh/rsync_key

# 复制公钥到远程服务器
ssh-copy-id -i ~/.ssh/rsync_key.pub user@remote-host

# 使用密钥进行 rsync
rsync -av -e "ssh -i ~/.ssh/rsync_key" /source/ user@remote:/destination/

2. 限制 SSH 访问

在远程服务器的 ~/.ssh/authorized_keys 中限制命令:

command="rsync --server -vlogDtpre.iLsfxC . /backup/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAAAB3...

3. 使用 chroot 环境

配置 rsync daemon 使用 chroot 环境以增加安全性。

与其他工具的比较

rsync vs scp

特性rsyncscp
增量传输
断点续传
压缩传输
保持属性
复杂过滤
性能中等

rsync vs cp

特性rsynccp
本地复制
远程复制
增量复制
进度显示
复杂过滤有限

自动化和定时任务

使用 cron 定时备份

bash
# 编辑 crontab
crontab -e

# 添加定时任务(每天凌晨2点执行备份)
0 2 * * * /usr/bin/rsync -av --delete /home/user/data/ /backup/daily/ >/var/log/backup.log 2>&1

# 每周日执行完整备份
0 3 * * 0 /usr/bin/rsync -av /home/user/data/ /backup/weekly/$(date +\%Y-\%m-\%d)/ >/var/log/weekly-backup.log 2>&1

使用 systemd timer

创建服务文件 /etc/systemd/system/backup.service

ini
[Unit]
Description=Daily Backup Service
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/rsync -av --delete /home/user/data/ /backup/daily/
User=backup
Group=backup

创建定时器文件 /etc/systemd/system/backup.timer

ini
[Unit]
Description=Daily Backup Timer
Requires=backup.service

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

启用定时器:

bash
sudo systemctl enable backup.timer
sudo systemctl start backup.timer

最佳实践

1. 备份策略

  • 3-2-1 规则:保持3份数据副本,存储在2种不同媒介上,其中1份异地存储
  • 增量备份:使用 --link-dest 选项创建基于硬链接的增量备份
  • 定期验证:定期验证备份的完整性和可恢复性

2. 性能优化

  • 网络传输:使用压缩选项 -z 和适当的压缩级别
  • 大文件传输:考虑使用 --inplace 选项
  • 并发传输:对于多个独立的同步任务,可以并行执行

3. 安全措施

  • 使用 SSH 密钥:避免使用密码认证
  • 限制访问权限:使用最小权限原则
  • 加密传输:确保敏感数据的传输安全

4. 监控和维护

  • 日志记录:保持详细的传输日志
  • 错误处理:在脚本中添加适当的错误处理
  • 定期检查:定期检查备份的完整性和脚本的运行状态

总结

rsync 是一个功能强大、灵活且高效的文件同步工具,适用于各种数据传输和备份场景。通过掌握其基本用法、高级功能和最佳实践,可以大大提高数据管理的效率和可靠性。

在使用 rsync 时,需要特别注意:

  • 源路径和目标路径的斜杠使用
  • 选择合适的选项组合
  • 在生产环境中使用前先进行测试
  • 定期验证备份的完整性

合理使用 rsync 可以帮助你建立可靠的数据备份和同步系统,确保重要数据的安全性和可用性。

MySQL删表操作详解:DELETE、TRUNCATE、DROP的区别与应用场景
Windows激活完整指南:MAS工具详解与多种激活方法