rsync —— 增量同步的事实标准

运维工具手册 03-文件与传输 6.0 KB 原文

rsync —— 增量同步的事实标准

分类:03 文件与传输 适用:Linux / macOS / Windows(cwRsync),协议 30/31 一句话:只传差异、能断点续传、能镜像删除,备份与发布的默认选择。

1. 它解决什么问题

  • 几 GB 目录每天同步,只改了几 MB,不想全量传。
  • 迁移服务器,要保留权限、属主、软链接、时间戳。
  • 做镜像站点,源端删了目标端也要删。
  • 限速同步,避免备份把业务带宽打满。

2. 安装

apt install -y rsync
dnf install -y rsync
apk add rsync
# Windows 用 cwRsync 或 WSL

两端版本差异太大时会提示协议不兼容,尽量保持 3.x。

3. 语法与最容易踩的斜杠

rsync [选项] 源 目标
rsync -av /data/ /backup/data/     # 同步 /data 的内容到 /backup/data
rsync -av /data  /backup/          # 同步 /data 目录本身 → /backup/data
写法 结果
/data/ 复制目录内容
/data 复制目录本身(目标下会多一层 data)

这条规则是 rsync 事故的头号来源。不确定就加 -n 先看。

4. 核心选项

选项 含义 备注
-a 归档模式 = -rlptgoD 保留软链、权限、时间、属主、设备
-v 详细 -vv 更细
-z 传输压缩 内网高带宽可关掉,省 CPU
-P --partial --progress 断点续传 + 进度条
-n / --dry-run 试运行 危险操作前必加
--delete 删除目标端多余文件 镜像同步
--delete-after 传输完再删 比默认更安全
--delete-excluded 连被排除的文件也从目标删 慎用
--exclude 排除模式 可多次
--include 包含模式 与 exclude 有顺序
--exclude-from=file 从文件读排除规则
--filter 完整过滤语法 最灵活
-e ssh 指定远程 shell -e 'ssh -p 2222'
--bwlimit=10m 限速 10MB/s 备份必备
--checksum 按校验和判断差异 慢但准,默认按大小+时间
--size-only 只比大小 快,可能漏
--inplace 直接写目标文件 省空间,非原子
--partial 保留中断的临时文件 大文件必备
--append 追加模式 只适合只增日志
--link-dest=DIR 硬链接未变化文件 增量备份省空间
--numeric-ids 不映射用户/组名 跨系统迁移用
--chown=user:group 强制属主
-H 保留硬链接
-A / -X 保留 ACL / xattr 需目标 FS 支持
--remove-source-files 传完删源 搬运场景
--max-delete=N 最多删 N 个 防误删护栏
--timeout=60 IO 超时 防挂死
--stats 传输统计
--log-file=FILE 日志

5. 远程同步(走 SSH)

# 推送到远程
rsync -avz -e 'ssh -p 2222' /data/ user@10.0.0.5:/backup/data/

# 从远程拉
rsync -avz user@10.0.0.5:/backup/data/ /data/

# 用密钥 + 指定配置
rsync -avz -e 'ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no' ...

免密是前提,否则 cron 任务会卡在密码提示。先在两台机器间配好 ssh-keygen + ssh-copy-id。

rsync daemon 模式(873 端口,适合大批机器):

# 服务端 /etc/rsyncd.conf
cat > /etc/rsyncd.conf <<'EOF'
uid = root
gid = root
use chroot = yes
max connections = 20
[backup]
  path = /data/backup
  read
  auth users = bkuser
  secrets file = /etc/rsyncd.secrets
EOF
echo 'bkuser:StrongPass123' > /etc/rsyncd.secrets
chmod 600 /etc/rsyncd.secrets
systemctl enable --now rsyncd

# 客户端
rsync -avz --password-file=/etc/rsync.pass bkuser@10.0.0.5::backup/ /local/

daemon 模式明文传输,跨公网必须套 VPN 或 SSH 隧道。

6. 排除规则怎么写

rsync -av --exclude='*.log' --exclude='cache/' --exclude='.git' /data/ /backup/
rsync -av --exclude-from=/etc/rsync-exclude.txt /data/ /backup/

/etc/rsync-exclude.txt:

*.tmp
*.log
cache/
node_modules/
.git/
/data/tmp/

规则要点:

  • 以 / 开头表示相对传输根;不以 / 开头匹配任意层级。
  • 以 / 结尾只匹配目录。
  • * 不跨 /,** 跨目录。
  • --include 与 --exclude 按出现顺序生效,先匹配先生效。

只同步某几类文件:

rsync -av --include='*/' --include='*.jpg' --exclude='*' /photos/ /backup/
# 注意必须先 include 目录,否则进不去

7. 实战场景

7.1 首次迁移服务器(保留一切属性)

# 源端执行,先试运行
rsync -avnHAX --numeric-ids --exclude={/proc,/sys,/dev,/tmp,/run,/var/cache} \
  / root@newhost:/

# 确认清单没问题后去掉 -n 正式跑

注意:/proc、/sys、/dev、/run 绝对不能同步;正在写入的数据库文件要停库或用快照。

7.2 增量备份 + 硬链接省空间

DEST=/backup/$(date +%F)
rsync -av --delete --link-dest=/backup/latest /data/ "$DEST/"
rm -f /backup/latest && ln -s "$DEST" /backup/latest

每天的备份目录里,没变的文件是硬链接,只有变化部分占新空间。几十天备份可能只占 1.2 倍空间。

7.3 限速备份,不影响业务

rsync -avz --bwlimit=20m --timeout=300 /data/ /backup/data/

--bwlimit 单位默认 KB/s,带 m 后缀是 MB/s。

7.4 断点续传大文件

rsync -avP --partial --append-verify bigfile.iso user@host:/data/

--append-verify 会在追加后校验,比 --append 安全。

7.5 只删目标端多余文件(不传新文件)

rsync -avn --delete /data/ /backup/data/     # 先看会删什么
rsync -av --delete --existing /data/ /backup/data/   # --existing 只更新已存在文件

7.6 同步大量小文件

rsync -av --no-compress --whole-file -e 'ssh -T -c aes128-gcm@openssh.com -o Compression=no' \
  /data/many-files/ user@host:/data/

小文件瓶颈在元数据与 SSH 加密开销,关压缩、用快加密算法能明显提速。文件超过十万,考虑先 tar 再传。

8. 危险操作与护栏

危险 后果 护栏
--delete 源目写反 把备份端的旧数据同步到源端,源端被删空 永远先 -n;加 --max-delete=100
/data 与 /data/ 混淆 目标下多一层或内容铺平 先 -n 看输出路径
同步 / 到已运行机器 覆盖系统文件致无法启动 排除 /proc /sys /dev /boot
同步数据库数据目录 文件不一致,库损坏 停库、FLUSH TABLES WITH READ LOCK 或快照
--remove-source-files 配错目标 源被删但目标没写成 先 -n,--remove-source-files 只删传输成功的文件,仍要谨慎

通用安全模板:

rsync -avn --delete --max-delete=100 --exclude-from=exclude.txt SRC/ DST/ | tee /tmp/plan.txt
# 人工确认 plan.txt 里没有意外的 "deleting"

9. 常见坑

  1. 尾部斜杠语义(重复强调):src vs src/ 结果不同。
  2. 默认按"大小 + mtime"判断差异:时钟不同步或 mtime 被改会导致漏传,用 --checksum 强制。
  3. --delete 与 --exclude 交互:被排除的文件默认不会在目标端删除;要删需 --delete-excluded。
  4. -a 不含 ACL 与 xattr:需要 -A -X,且目标文件系统要支持。
  5. 根用户同步普通用户文件会改属主:跨系统用 --numeric-ids 或 --chown。
  6. -z 对已压缩文件无效:jpg/zip/mp4 再压缩只浪费 CPU。
  7. --inplace 不是原子操作:中途失败会留下半个文件,不适合关键数据。
  8. --append 只判断大小,不校验内容:源文件被改写会导致数据错位,用 --append-verify。
  9. SELinux 环境丢失上下文:加 -X 或在目标端 restorecon -R。
  10. cron 里跑 rsync 找不到密钥:cron 环境无 SSH_AUTH_SOCK,用 -i 指定私钥并确保权限 600。
  11. 跨文件系统 -H 硬链接可能失效,且大量硬链接会拖慢。
  12. rsync 不处理正在打开的文件:日志类文件建议先 flush 或用 --ignore-existing。

10. 速查表

rsync -avn SRC/ DST/                          # 试运行(第一步永远是它)
rsync -av SRC/ DST/                           # 本地同步
rsync -avz SRC/ user@host:DST/                # 远程推送
rsync -avz user@host:SRC/ DST/                # 远程拉取
rsync -avz -e 'ssh -p 2222' SRC/ host:DST/    # 非标端口
rsync -avP --partial SRC/ DST/                # 断点续传
rsync -av --delete --max-delete=100 SRC/ DST/ # 镜像(带护栏)
rsync -av --exclude-from=ex.txt SRC/ DST/     # 排除规则
rsync -av --bwlimit=20m SRC/ DST/             # 限速
rsync -av --link-dest=/backup/latest SRC/ /backup/$(date +%F)/   # 增量备份
rsync -av --checksum SRC/ DST/                # 按校验和
rsync -av --stats SRC/ DST/                   # 统计
rsync —— 增量同步的事实标准 - 知识库 - 起航社区