本文目录导读:

rsync 实现文件夹增量同步的核心机制是分块校验和传输,并结合文件大小和修改时间进行快速判断,它并不是每次传输整个文件,而是只传输源目录和目标目录之间的差异部分。
以下是其实现增量同步的详细步骤和关键机制:
核心原理:分块校验与滚动哈希
rsync 拥有一种非常高效的算法,能够只传输文件的变更部分。
-
输入端(发送端):
- 将源文件分割成一系列固定大小的数据块(通常是 700 到 1000 字节)。
- 对每个数据块计算两种类型的校验和:一个弱校验(滚动哈希,Rolling Checksum)和一个强校验(MD5 或 MD4)。
- 将这些校验和列表发送给接收端。
-
输出端(接收端,即目标端):
- 接收输入端的校验和列表。
- 在目标端的旧文件上,以一个字节为单位向后滑动,为每个位置生成一个滚动哈希(弱校验)。
- 滚动哈希的作用是可以根据前一个位置的哈希值快速计算下一个位置的哈希值(无需重新处理整个文件)。
- 如果滚动哈希匹配了来自输入端的检验和中的某个弱校验,则计算这个位置的强校验(MD5)并与输入端的强校验进行二次比对。
- 如果强校验也相同,说明这块数据在两个文件中完全一致,无需传输,接收端将这个匹配的块重新组合到目标文件中。
- 如果强校验不匹配,或者滚动哈希完全没匹配上,则说明这块数据是变更过的。
-
最终交换:
- 匹配的数据块:直接使用接收端本地已有的数据块,无需网络传输。
- 不匹配的数据块:发送端将这些变更过的数据块(及其在文件中的位置信息)发送给接收端。
- 接收端将本地的匹配块和接收到的变更块组合,生成完整的、与源文件一致的新文件。
总结一下:rsync 通过将文件切块,比对校验和,只传输真正改变了的数据块,这就是它实现“增量同步”的根本原因。
如何让 rsync 正确使用增量机制(常用参数)
默认情况下,rsync 会尝试使用其增量传输算法,但某些参数会强制它进行完整文件复制,为了确保增量同步,你需要正确使用以下参数:
rsync -avz --progress /path/to/source/ /path/to/destination/
-v(verbose):显示详细信息,帮助你了解传输过程。-z(compress):在传输过程中压缩数据,节省带宽(对文本文件效果显著)。-a(archive):这是增量同步的关键,它包含了-r(递归)、-l(保留符号链接)、-p(保留权限)、-t(保留修改时间)、-g(保留组)、-o(保留所有者)等选项。-t是极其重要的,因为它保留了文件的修改时间戳。--progress:显示每个文件的传输进度。
-a 参数(尤其是 -t)如何辅助增量同步?
- 当 rsync 启动时,它首先会比较源文件和目标文件的大小和修改时间(
mtime)。 - 如果大小和修改时间相同,rsync 会默认文件没有变化,直接跳过该文件,完全不进入分块校验的流程。
- 如果大小或修改时间不同,则文件被认为发生了改变,rsync 会启动其核心的分块校验和增量传输算法。
-a(或 -t)是增量同步的前提:它让 rsync 快速过滤掉大量未变化文件,只对少数变化的文件执行增量算法。
常见场景与命令示例
场景1:本地文件夹同步(增量备份)
# 同步 /home/project/ 到 /mnt/backup/project/ # 只传输新文件和修改过的文件部分 rsync -av --delete /home/project/ /mnt/backup/project/
--delete:删除目标端有但源端没有的文件(保持两端完全一致)。- 增量体现在:
-a先跳过未改文件;对改过的文件,rsync 算法只传差异块。
场景2:远程同步(通过 SSH)
# 将本地文件夹增量同步到远程服务器 rsync -avz -e "ssh -p 2222" /local/folder/ user@remote:/remote/folder/ # 从远程服务器增量拉取数据到本地 rsync -avz -e "ssh -p 2222" user@remote:/remote/folder/ /local/folder/
-e "ssh -p 2222":指定使用 SSH 连接,并设置端口。- 整个过程都是一样的增量算法。
场景3:强制增量同步(即使文件认为未变)
# 如果目标文件的时间戳被意外修改,但实际内容未变,rsync 可能会跳过它。 # 可以使用 --checksum(-c)强制基于校验和比较所有文件。 rsync -av --checksum /source/ /dest/ # 注意:--checksum 会读取所有文件内容来计算 MD5,比只比较时间和大小要慢得多,仅在需要绝对精确比对时使用。
场景4:仅同步文件的一部分(类似断点续传)
# 使用 --partial 保留未完全传输的文件 rsync -av --partial /largefile.zip /destination/
--partial:如果传输中断,会保留已传输的部分数据,下次运行时,rsync 会基于这个不完整的文件启动增量算法,只传输缺失的部分,从而实现类似断点续传的效果。
可能遇到的问题与总结
| 常见问题 | 原因 | 解决办法 |
|---|---|---|
| 每次都全部传输 | 忘记加 -a 或 -t |
添加 -a 参数或手动使用 -t -l -p -r 等。 |
| 速度很慢 | 网络差或文件数量极多 | 添加 -z(压缩)、--no-compress(针对已压缩文件)、或使用 --filter 排除非必要目录。 |
| 每次传输都被当做新文件 | 源文件和目标文件修改时间不同(例如磁盘格式差异) | 尝试使用 --size-only(仅比较大小)或 --checksum(强制校验和)。 |
| 删除目标端多余文件 | 未加 --delete |
添加 --delete 参数(注意:这是单向同步)。 |
- rsync 的增量同步由分块校验和算法和时间/大小快速比较两层机制共同完成。
-a(或-t) 是触发快速跳过未变化文件的关键。- 分块校验 是面向“已变化文件”的精髓,只传输文件内改变了的数据块。
- 正确使用参数(-avz --delete) 即可实现高效、可靠的文件夹增量同步。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。