如果你最初接触 rsync,是在某个运维群里复制到一条命令,十有八九是这条:rsync -avz。小文件同步时一切安好,觉得它不过就是个高级版 cp。直到某天你把几百 G 的日志目录从服务器 A 同步到服务器 B,同步完却发现目标目录里堆满了早该消失的旧文件;或者同步中断后你决定从头再来,白白等了三个小时。那一刻你才会承认,rsync 里几乎每个参数都有脾气,而"会用"和"用得明白"之间,隔着一层实在的运维经验。
这篇内容适合什么人看?正在给服务器做数据迁移的新手运维、经常要在本地和远端之间同步代码和资源的开发,以及所有想把"复制文件"这件事做出版本感的人。rsync 不是唯一能传文件的工具,却是 Linux 生态里少有的"传完还能讲清楚增量逻辑"的同步工具。这篇我不讲命令手册上能查到的照搬内容,重点说清楚那些真正影响你判断的参数、组合和踩坑经验。
1. rsync 到底比 cp 和 scp 强在哪:增量同步的真实逻辑
1.1 从"重复传了整天才发现根本没增量"说起
很多人一开始没有直观感受,觉得 scp 也能传目录,rsync 不过多了一个压缩选项。直到你面对这样的场景:一台服务器上有 200 万个小图片,总共 30GB,每天新增 20%,你需要把它们同步到另一台机器做备份。
用 scp 的话,每天都要从头到尾把 30GB 全部传一遍,因为 scp 没有"上次传过什么"的记忆。用 cp -r 在本地拷贝,同样会把所有文件完整写一遍,即使目标位置已经存在同名同内容的文件。
rsync 不一样。它的增量逻辑不是靠"名字在不在"来判断,而是先判断两个文件的**"大小+修改时间"**是否一致。如果大小和 mtime 都相同,rsync 默认认为文件内容没有变化,直接跳过。
这就是你不加任何额外参数时它快的根本原因:它不是传输工具,而是"比较工具 + 传输工具"的结合。理解这一层,你就不会再疑惑"为什么同样的目录,第一次跑很慢,第二次跑只需要几秒"。
1.2 快速跳过与真正的块级校验:--checksum 的取舍
但是这里有个坑:如果文件内容变了,但大小恰好没变,而 mtime 又被人为改过,rsync 的默认快速判断就会漏掉这个文件。
比如最常见的场景:程序在服务器上把某个日志文件改名、复制、再重置时间戳;或者从 Git 仓库 checkout 出来的文件,mtime 是固定的 commit 时间,但内容在两个分支间可能不同。
此时你需要 -c / --checksum 参数。它会强制 rsync 对每个候选文件做内容校验,而不只看 mtime。注意我用的词是"候选文件"——rsync 不会真的把所有文件逐字节读取,它会先比较大小,如果大小不同就必定传输,只有大小相同才进入校验阶段。所以 -c 并不会像很多人想的那样让速度慢到不可用,在大文件数量多、但单个文件体积小的场景下开销可以接受。
实际选择:
| 场景 | 是否加 -c | 理由 |
|---|---|---|
| 常规代码部署、日志同步 | 否 | 依赖 mtime+size 足够可靠,速度快 |
| 双机热备中的关键数据目录 | 是 | 必须保证任何文件变化都被识别 |
| 文件数量极大、单文件很小(几十万文件量) | 否 | 全量校验的开销可能在扫描阶段就拖垮性能 |
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 三种 rsync 使用形态与它们的边界:本地、SSH、daemon
2.1 本地目录同步:最简单也最容易忘掉 / 的场景
很多教程会把本地同步一笔带过,但它其实是理解 rsync 路径语义最好的入门例子。最典型的错误,是分不清这两条命令的区别:
bash复制rsync -av /data/project/ /backup/project/
rsync -av /data/project /backup/
第一条命令里的源路径以 / 结尾,rsync 会把 /data/project/ 这个目录的内容拷贝到 /backup/project/ 之下。第二条命令源路径不以 / 结尾,rsync 会把整个 project 目录本身拷贝过去,最终你会得到 /backup/project/project/。
我见过很多新人在写 crontab 备份脚本时踩这个坑:想备份目录内容,结果每一轮备份都在目标目录里多套一层。所以最简单的记忆方式是:源路径末尾有没有斜杠,决定了你是"搬整个盒子"还是"搬盒子里的东西"。 目标路径末尾的斜杠则更多地是一个"必须配合目录存在性"的细节。
本地同步还有一个很实用的场景:跨磁盘移动目录,比如把 /var/lib/docker 迁到数据盘 /data/docker。直接 mv 在同一文件系统内是元数据操作,一瞬间完成;跨文件系统时 mv 本质也是先复制后删除,此时如果中途断电你可能会面临部分文件已复制、部分未复制的烂摊子。rsync 的好处不只是能断点续传,它还有一个天然优势:传输完成前会写临时文件,完成后再 rename 到目标位置,数据完整性更可控。
执行迁移时建议带上 --remove-source-files 吗?我不太推荐。文件迁移用的妥当做法是先用不带删除的普通同步,确认目标目录完整无误后,再手动校验文件数量,最后用 --remove-source-files 二次清理源端空文件,或者干脆手动删除源目录。上来就加这个参数,一旦中途出差错,源文件清理了一批,目标又没完整,恢复就麻烦了。
2.2 走 SSH 通道的远程同步:单双向、自定义端口与免密
远程同步里最常见的形态是通过 SSH 隧道传输,好处是无需额外启动任何服务,只要两端都有 rsync 和 SSH 权限即可工作。
bash复制rsync -avz /data/web/ user@192.168.1.20:/data/web/
从本地推送到远端。反向则是从远端拉取:
bash复制rsync -avz user@192.168.1.20:/data/web/ /data/backup/
这两条命令方向性的理解非常重要。rsync 习惯把同步的发起端写在前面,也就是源路径在前。很多从 Windows 同步工具转过来的用户,会下
