Rsync 完全使用指南

目录

概述

什么是 Rsync?

Rsync(Remote Synchronization)是一个开源的文件同步和传输工具,最初由 Andrew Tridgell 和 Paul Mackerras 于1996年开发。它采用智能的增量传输算法,能够高效地在本地或远程系统间同步文件和目录。

核心特性

  1. 增量传输:仅传输源文件和目标文件之间的差异部分
  2. 完整性检查:使用校验和确保数据传输的准确性
  3. 保持属性:保留文件权限、时间戳、所有者等元数据
  4. 多种传输模式:支持本地、远程(通过SSH或rsync守护进程)传输
  5. 压缩传输:可选的传输时压缩以减少带宽占用
  6. 灵活的过滤规则:强大的包含/排除文件模式匹配

工作原理

Rsync 使用 "rsync算法" 进行快速增量文件传输: 1. 发送方将文件分割为固定大小的块 2. 为每个块生成两个校验和:一个强校验(MD5)和一个弱校验 3. 接收方检查已有文件的块校验和 4. 仅传输不匹配的块和新数据

安装与配置

各平台安装方法

Linux

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install rsync

# RHEL/CentOS/Fedora
sudo yum install rsync
# 或
sudo dnf install rsync

# Arch Linux
sudo pacman -S rsync

# 验证安装
rsync --version

macOS

# macOS 预装版本通常较旧,建议更新:
brew install rsync

# 或将新版本链接到系统路径
brew link --override rsync

Windows

# 方法1:通过 WSL(推荐)
# 启用 WSL 后,安装 Linux 发行版即可使用

# 方法2:Git for Windows
# Git Bash 中自带 rsync

# 方法3:Cygwin
# 安装时选择 rsync 包

# 方法4:直接安装 cwRsync
# 商业版本,提供Windows原生支持

Rsync 守护进程配置(可选)

服务端配置

# 1. 编辑配置文件
sudo nano /etc/rsyncd.conf

# 示例配置
uid = nobody
gid = nobody
use chroot = yes
max connections = 4
pid file = /var/run/rsyncd.pid
log file = /var/log/rsync.log

[backup]
    path = /data/backup
    comment = Backup Area
    read only = no
    list = yes
    auth users = backupuser
    secrets file = /etc/rsyncd.secrets

# 2. 创建密码文件
sudo nano /etc/rsyncd.secrets
# 格式:username:password
backupuser:securepassword123

# 3. 设置权限
sudo chmod 600 /etc/rsyncd.secrets

# 4. 启动服务
sudo systemctl start rsync
sudo systemctl enable rsync

基本语法与选项

命令语法

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

常用选项详解

基本选项

选项 说明 示例
-v, --verbose 详细输出 rsync -v source dest
-q, --quiet 静默模式 rsync -q source dest
-n, --dry-run 试运行,不实际执行 rsync -n source dest
-h, --human-readable 人类可读格式输出 rsync -h source dest

复制选项

选项 说明 等效组合
-a, --archive 归档模式(递归+保留所有属性) -rlptgoD
-r, --recursive 递归复制目录
-l, --links 保留符号链接
-p, --perms 保留权限
-t, --times 保留修改时间
-g, --group 保留属组
-o, --owner 保留属主(需要root权限)
-D 保留设备文件和特殊文件

同步选项

选项 说明 注意
--delete 删除目标中源不存在的文件 谨慎使用
--delete-before 传输前删除目标文件
--delete-during 传输过程中删除(默认)
--delete-after 传输后删除 更安全
--ignore-existing 跳过目标已存在的文件
--update 仅更新比源旧的文件

过滤选项

选项 说明 示例
--exclude=PATTERN 排除匹配模式的文件 --exclude='*.tmp'
--include=PATTERN 包含匹配模式的文件 --include='*.txt'
--exclude-from=FILE 从文件读取排除模式 --exclude-from=exclude.txt
--include-from=FILE 从文件读取包含模式
-C, --cvs-exclude 排除CVS自动忽略的文件

传输选项

选项 说明 示例
-z, --compress 传输时压缩 rsync -z source dest
--compress-level=NUM 压缩级别(1-9) --compress-level=6
--partial 保留部分传输的文件 断点续传
--progress 显示传输进度
-P --partial --progress 组合 rsync -P source dest
--bwlimit=RATE 限制带宽(KB/s) --bwlimit=1000

远程选项

选项 说明 示例
-e, --rsh=COMMAND 指定远程shell -e ssh
--rsync-path=PROGRAM 指定远程rsync路径 --rsync-path=/usr/local/bin/rsync
--port=PORT 指定SSH/rsync端口 --port=2222

路径格式说明

# 本地路径
/path/to/local/dir
/path/to/local/file

# 远程路径(通过SSH)
user@host:/path/to/remote/dir
user@host:/path/to/remote/file

# 远程路径(通过rsync守护进程)
host::module/path
user@host::module/path
rsync://host:port/module/path

# 重要:目录斜杠的区别
source/      # 复制目录内容到目标
source       # 复制整个目录到目标

使用场景与示例

1. 本地文件同步

基本备份

# 备份目录到另一个位置
rsync -av ~/Documents/ /mnt/backup/Documents/

# 验证备份
diff -r ~/Documents/ /mnt/backup/Documents/

镜像同步

# 创建完全相同的镜像(删除目标多余文件)
rsync -av --delete /source/ /destination/

# 安全版本:先试运行
rsync -avn --delete /source/ /destination/

大文件同步

# 使用压缩和进度显示
rsync -avzP /path/to/large/files/ /backup/large/

# 限制带宽使用(避免影响网络)
rsync -avz --bwlimit=5000 --progress /source/ /destination/

2. 远程文件传输

备份到远程服务器

# 使用SSH加密传输
rsync -avz -e ssh ~/data/ user@remote.server.com:/backup/data/

# 使用非标准SSH端口
rsync -avz -e "ssh -p 2222" ~/data/ user@remote.server.com:/backup/

# 使用SSH密钥认证(无需密码)
rsync -avz -e "ssh -i ~/.ssh/id_rsa" ~/data/ user@server:/backup/

从远程服务器拉取

# 拉取远程目录到本地
rsync -avz user@server:/remote/data/ ~/local/backup/

# 拉取并删除本地多余文件
rsync -avz --delete user@server:/remote/data/ ~/local/mirror/

服务器间同步

# 通过本地中转
rsync -avz server1:/data/ /tmp/data/
rsync -avz /tmp/data/ server2:/backup/

# 直接同步(需要双向访问权限)
ssh user@server1 "rsync -avz /data/ user@server2:/backup/"

3. 特殊场景处理

同步符号链接

# 不同处理方式对比
rsync -l source/ dest/          # 复制为符号链接
rsync -L source/ dest/          # 复制链接指向的实际文件
rsync -K source/ dest/          # 将目标符号链接视为普通目录

处理权限问题

# 保持权限(需要相应权限)
sudo rsync -av /source/ /destination/

# 不保留属主(避免权限问题)
rsync -av --no-owner --no-group source/ dest/

# 设置统一权限
rsync -av --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r source/ dest/

排除特定文件

# 多种排除方式示例
rsync -av --exclude='*.tmp' --exclude='*.log' source/ dest/

# 排除目录
rsync -av --exclude='temp/' --exclude='cache/' source/ dest/

# 使用排除文件
cat > exclude-list.txt << EOF
*.tmp
*.log
.temp/
cache/
.DS_Store
Thumbs.db
EOF
rsync -av --exclude-from='exclude-list.txt' source/ dest/

包含特定文件

# 先排除所有,再包含特定模式
rsync -av --exclude='*' --include='*.txt' --include='*.md' source/ dest/

# 包含目录结构
rsync -av --exclude='*' --include='*/' --include='*.txt' source/ dest/

4. 增量备份策略

每日增量备份

#!/bin/bash
# daily-backup.sh

SOURCE="/home/user/data/"
DEST_BASE="/mnt/backup/"
LOG_DIR="/var/log/backups"

# 创建基于日期的目录
DATE=$(date +%Y-%m-%d)
DEST="${DEST_BASE}${DATE}/"
LATEST="${DEST_BASE}latest/"

# 创建目标目录
mkdir -p "$DEST"

# 从最新备份创建硬链接,然后同步
if [ -d "$LATEST" ]; then
    cp -al "$LATEST"/* "$DEST/" 2>/dev/null
fi

# 执行同步
rsync -av --delete \
    --link-dest="$LATEST" \
    "$SOURCE" "$DEST" \
    >> "${LOG_DIR}/backup-${DATE}.log" 2>&1

# 更新最新备份链接
rm -f "$LATEST"
ln -s "$DEST" "$LATEST"

echo "备份完成: $(date)" >> "${LOG_DIR}/backup-${DATE}.log"

高级功能

1. 部分传输与恢复

# 启用部分传输(支持断点续传)
rsync --partial --progress source/ dest/

# 指定部分文件存放目录
rsync --partial-dir=.rsync-partial --progress source/ dest/

# 恢复中断的传输
rsync --append source/ dest/

2. 比较与校验

# 仅比较文件而不传输
rsync -avnc source/ dest/

# 详细比较
rsync -avn --itemize-changes source/ dest/
# 输出解释:
# >f+++++++++ 新文件
# .f..t...... 时间戳不同
# .f.s......  大小不同
# .f.......... 文件相同

# 基于校验和的比较(更准确但更慢)
rsync -avc source/ dest/

3. 批量同步脚本

#!/bin/bash
# multi-sync.sh

CONFIG_FILE="sync-config.txt"
LOG_FILE="sync-$(date +%Y%m%d).log"

# 配置文件格式:源路径:目标路径:排除文件(可选)
# /home/user/docs:/backup/docs:exclude-docs.txt
# user@server:/data:/local/backup:exclude-server.txt

while IFS=: read -r SOURCE DEST EXCLUDE; do
    echo "同步: $SOURCE -> $DEST" | tee -a "$LOG_FILE"

    EXCLUDE_OPT=""
    if [ -n "$EXCLUDE" ] && [ -f "$EXCLUDE" ]; then
        EXCLUDE_OPT="--exclude-from=$EXCLUDE"
    fi

    rsync -avz --delete $EXCLUDE_OPT \
        "$SOURCE" "$DEST" \
        >> "$LOG_FILE" 2>&1

    if [ $? -eq 0 ]; then
        echo "成功: $SOURCE" | tee -a "$LOG_FILE"
    else
        echo "失败: $SOURCE (代码: $?)" | tee -a "$LOG_FILE"
    fi
    echo "---" | tee -a "$LOG_FILE"
done < "$CONFIG_FILE"

4. 实时监控与同步

# 使用inotify-tools监控目录变化
#!/bin/bash
# realtime-sync.sh

SOURCE="/path/to/watch"
DEST="user@remote:/backup/"
EXCLUDE=".git/ node_modules/ *.tmp"

# 安装inotify-tools(如果需要)
# sudo apt-get install inotify-tools

inotifywait -m -r -e modify,create,delete,move "$SOURCE" |
while read -r directory events filename; do
    echo "检测到变化: $events $directory$filename"

    # 构建排除参数
    EXCLUDE_ARGS=""
    for pattern in $EXCLUDE; do
        EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude='$pattern'"
    done

    # 执行同步
    eval "rsync -avz --delete $EXCLUDE_ARGS $SOURCE $DEST"

    echo "同步完成: $(date)"
done

性能优化

1. 网络优化

# 调整块大小(适合大文件)
rsync -av --block-size=8192 source/ dest/

# 禁用压缩(当CPU是瓶颈时)
rsync -av --no-compress source/ dest/

# 并行传输多个文件
# 使用parallel工具配合rsync
find /source -type f | parallel -j 4 rsync -av {} /dest/

2. 磁盘I/O优化

# 减少磁盘写入(适合SSD)
rsync -av --inplace source/ dest/

# 预分配空间(减少碎片)
rsync -av --preallocate source/ dest/

# 使用稀疏文件处理
rsync -av --sparse source/ dest/

3. 内存使用优化

# 限制内存使用
rsync -av --max-size=100M source/ dest/

# 分批处理大量小文件
find /source -type f -name "*.txt" -exec rsync -av {} /dest/ \;

故障排除

常见问题与解决方案

1. 连接问题

# 错误:ssh: connect to host xxx port 22: Connection refused
# 解决方案:
rsync -av -e "ssh -p 2222" source/ user@host:/dest/  # 指定端口
ssh -v user@host  # 测试SSH连接

# 错误:rsync: connection unexpectedly closed
# 解决方案:
rsync -av --timeout=30 source/ dest/  # 增加超时时间
rsync -av --contimeout=30 source/ dest/  # 增加连接超时

2. 权限问题

# 错误:rsync: mkstemp failed: Permission denied (13)
# 解决方案:
sudo rsync -av source/ dest/  # 使用sudo
rsync -av --no-p --no-g source/ dest/  # 不保留权限
rsync -av --chmod=ugo=rwX source/ dest/  # 修改权限

# 错误:rsync: failed to set times on "/dest/file": Operation not permitted
rsync -av --no-t source/ dest/  # 不保留时间戳

3. 磁盘空间问题

# 检查可用空间
df -h /dest

# 使用试运行检查需求
rsync -avn source/ dest/ | grep "total size"

# 排除大文件
rsync -av --max-size=1G source/ dest/

4. 文件系统限制

# 处理特殊字符
rsync -av --iconv=utf-8,ascii source/ dest/

# 处理长路径
rsync -av --no-protect-args source/ dest/

调试模式

# 增加详细级别
rsync -avvv source/ dest/

# 记录详细日志
rsync -av --log-file=rsync.log --log-file-format="%i %n%L" source/ dest/

# 检查rsync协议版本
rsync --version

安全注意事项

1. 传输安全

# 始终使用SSH加密
rsync -av -e "ssh -o StrictHostKeyChecking=yes" source/ dest/

# 禁用主机密钥检查(仅测试环境)
rsync -av -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" source/ dest/

# 使用SSH密钥而非密码
ssh-keygen -t rsa -b 4096
ssh-copy-id user@host
rsync -av -e "ssh -i ~/.ssh/id_rsa" source/ user@host:/dest/

2. 认证安全

# 使用rsync守护进程时的安全配置
# /etc/rsyncd.conf 中设置:
read only = yes  # 只读访问
hosts allow = 192.168.1.0/24  # IP限制
auth users = username  # 需要认证
secrets file = /etc/rsyncd.secrets  # 密码文件

# 密码文件权限
chmod 600 /etc/rsyncd.secrets

3. 输入验证

# 防止路径遍历攻击
# 使用chroot
use chroot = yes

# 验证源和目标路径
if [[ ! "$SOURCE" =~ ^/allowed/path/ ]]; then
    echo "非法源路径"
    exit 1
fi

4. 审计与监控

# 记录所有同步操作
rsync -av --log-file=/var/log/rsync/$(date +%Y%m%d).log source/ dest/

# 使用系统审计
sudo auditctl -w /usr/bin/rsync -p x

脚本自动化

1. 完整的备份脚本

#!/bin/bash
# complete-backup.sh

# 配置
SOURCE_DIRS=(
    "/home/user/Documents"
    "/home/user/Projects"
    "/etc"
    "/var/www"
)
BACKUP_ROOT="/mnt/backup"
LOG_DIR="/var/log/backups"
RETENTION_DAYS=30
EMAIL_NOTIFY="admin@example.com"

# 初始化
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="$BACKUP_ROOT/$TIMESTAMP"
LOG_FILE="$LOG_DIR/backup_$TIMESTAMP.log"
EXCLUDE_FILE="$HOME/.backup_exclude"

# 创建目录
mkdir -p "$BACKUP_DIR"
mkdir -p "$LOG_DIR"

# 开始备份
echo "=== 备份开始: $(date) ===" | tee -a "$LOG_FILE"
echo "备份目录: $BACKUP_DIR" | tee -a "$LOG_FILE"

# 备份每个目录
for SOURCE in "${SOURCE_DIRS[@]}"; do
    if [ -d "$SOURCE" ]; then
        DIR_NAME=$(basename "$SOURCE")
        echo "备份: $SOURCE -> $BACKUP_DIR/$DIR_NAME" | tee -a "$LOG_FILE"

        rsync -av --delete \
            --exclude-from="$EXCLUDE_FILE" \
            --link-dest="$BACKUP_ROOT/latest/$DIR_NAME" \
            "$SOURCE/" "$BACKUP_DIR/$DIR_NAME/" \
            >> "$LOG_FILE" 2>&1

        if [ $? -eq 0 ]; then
            echo "成功: $SOURCE" | tee -a "$LOG_FILE"
        else
            echo "警告: $SOURCE 备份有问题" | tee -a "$LOG_FILE"
        fi
    else
        echo "错误: $SOURCE 不存在" | tee -a "$LOG_FILE"
    fi
done

# 创建最新备份链接
rm -f "$BACKUP_ROOT/latest"
ln -s "$BACKUP_DIR" "$BACKUP_ROOT/latest"

# 清理旧备份
find "$BACKUP_ROOT" -maxdepth 1 -type d -name "20*" -mtime +$RETENTION_DAYS \
    -exec echo "删除旧备份: {}" \; \
    -exec rm -rf {} \; \
    >> "$LOG_FILE" 2>&1

# 发送通知
if [ -n "$EMAIL_NOTIFY" ]; then
    mail -s "备份完成: $(date)" "$EMAIL_NOTIFY" < "$LOG_FILE"
fi

echo "=== 备份结束: $(date) ===" | tee -a "$LOG_FILE"

2. 配置文件管理

# .rsync-config 示例
SOURCE="user@server:/data/"
DEST="/local/backup/"
OPTIONS="-avz --delete --progress"
EXCLUDE="--exclude='*.tmp' --exclude='cache/'"
SCHEDULE="0 2 * * *"  # 每天凌晨2点

# 使用配置文件的脚本
#!/bin/bash
CONFIG_FILE="$HOME/.rsync-config"

if [ -f "$CONFIG_FILE" ]; then
    source "$CONFIG_FILE"
    rsync $OPTIONS $EXCLUDE "$SOURCE" "$DEST"
else
    echo "配置文件不存在: $CONFIG_FILE"
    exit 1
fi

3. 系统服务配置

# /etc/systemd/system/rsync-backup.service
[Unit]
Description=Rsync Backup Service
After=network.target

[Service]
Type=oneshot
User=backupuser
ExecStart=/usr/local/bin/backup-script.sh
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target

# /etc/systemd/system/rsync-backup.timer
[Unit]
Description=Daily Rsync Backup

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

附录

A. 常用命令速查表

# 基础备份
rsync -av source/ dest/

# 远程备份
rsync -avz -e ssh local/ user@remote:/backup/

# 镜像同步
rsync -av --delete source/ dest/

# 试运行
rsync -avn source/ dest/

# 带进度和断点续传
rsync -avzP source/ dest/

# 排除文件
rsync -av --exclude='*.tmp' source/ dest/

# 带宽限制
rsync -av --bwlimit=1000 source/ dest/

B. 退出代码含义

代码 含义 建议操作
0 成功 无需操作
1 语法或用法错误 检查命令语法
2 协议不兼容 更新rsync版本
3 文件选择/IO错误 检查文件权限
4 不支持的操作 检查选项兼容性
5 协议启动失败 检查网络连接
10 socket IO错误 检查网络/防火墙
11 文件IO错误 检查磁盘空间/权限
12 协议数据流错误 重试传输
13 进程统计错误 检查系统资源
14 套接字错误 检查网络配置
20 收到SIGUSR1/SIGINT 用户中断
21 等待子进程出错 检查系统状态
22 错误分配核心内存 检查系统内存
23 部分传输 使用--partial重试
24 文件 vanished 源文件在传输中删除

C. 性能测试方法

# 创建测试文件
dd if=/dev/zero of=testfile bs=1M count=100

# 测试本地传输速度
time rsync -av testfile /tmp/

# 测试网络传输速度
time rsync -av testfile user@remote:/tmp/

# 测试压缩效果
rsync -avz testfile /tmp/
# 对比有/无压缩的传输时间

D. 相关工具与替代方案

  1. rsnapshot - 基于rsync的备份工具
  2. lsyncd - 实时同步守护进程
  3. unison - 双向同步工具
  4. syncthing - P2P文件同步
  5. rclone - 云存储同步工具
  6. borgbackup - 去重备份工具

E. 学习资源

  1. 官方文档:man rsync
  2. Rsync官网:https://rsync.samba.org/
  3. GitHub仓库:https://github.com/WayneD/rsync
  4. Rsync教程:https://download.samba.org/pub/rsync/rsync.html

最后更新日期: $(date +%Y-%m-%d)

版本: 1.0

注意事项: 在实际生产环境中使用前,请务必在测试环境中验证所有命令和脚本。