rsync同步技术
rsync 是 Linux/Unix 下经典的远程同步工具,以增量传输和灵活的文件过滤闻名,广泛用于备份、镜像、部署等场景。下面从核心原理到实战技巧,做一个系统梳理。
一、rsync 的核心算法:如何实现增量同步
rsync 的高效不在于“拷贝”,而在于 只传输差异部分。其算法由 Andrew Tridgell 设计,分三步走:
1. 分块与弱校验和
- 接收方(目标端)将已存在的旧文件按固定块大小(如 512 字节)分块。
- 对每一块计算两个校验和:
- 弱校验和(滚动校验和):基于 Adler-32 或更早的算法,计算速度极快,可“滚动”计算(即已知字节序列
A1...Ak的校验和,可快速算出A2...Ak+1的)。 - 强校验和:如 MD5,避免弱校验碰撞。
- 弱校验和(滚动校验和):基于 Adler-32 或更早的算法,计算速度极快,可“滚动”计算(即已知字节序列
2. 发送方匹配块
- 发送方(源端)收到弱/强校验和列表后,对自己的新文件进行逐字节滚动计算弱校验和。
- 当弱校验和匹配时,再用强校验和确认是否为同一块。
- 匹配成功 → 记录“匹配块号”,不需要发送该块的实际数据。
- 未匹配的字节 → 记录为“字面量数据”。
3. 生成差异指令并重建
- 发送方把匹配指令(如“从旧文件复制第N块”)和未匹配的原始数据混合成指令流,发给接收方。
- 接收方根据指令,从本地旧文件取出匹配块,并穿插写入新数据,在临时文件中组装出新文件,最后原子重命名覆盖。
关键优势:网络传输的只是“无法在旧文件中找到的字节”+ 少量校验和与指令,因此带宽消耗极低,特别适合大文件少量修改的场景。
二、基本用法与模式
rsync 支持两种传输方式:远程 Shell(SSH) 和 rsync 守护进程。
语法格式
rsync [选项] 源 目标
1. 本地复制(相当于cp的增强版)
rsync -av /data/project/ /backup/project/
-a:归档模式,保留权限、时间、软链接等,等价于-rlptgoD。/结尾:表示拷贝目录内容,不加则拷贝目录本身。
2. 通过 SSH 同步远程主机
# 推送:本地→远程
rsync -avz -e ssh /local/dir/ user@remote:/remote/dir/
# 拉取:远程→本地
rsync -avz user@remote:/remote/dir/ /local/dir/
-z:传输时压缩,适合低带宽链路。-e ssh:指定远程Shell为SSH,通常可省略(默认即SSH)。
3. 使用 rsync 守护进程(rsync://)
rsync -avz rsync://backup-server/module /local/dest
# 或使用双冒号语法
rsync -avz user@backup-server::module /local/dest
需在服务端配置 /etc/rsyncd.conf 定义模块。
三、必知关键选项
| 选项 | 作用 |
|---|---|
-a, --archive |
归档模式,保留几乎所有属性 |
-v, --verbose |
详细输出 |
-z, --compress |
传输时压缩 |
-P |
等价于 --partial --progress,支持断点续传并显示进度 |
--delete |
目标端删除源端不存在的文件(镜像同步) |
--delete-excluded |
同时删除被排除的文件(慎用) |
--delete-delay |
延迟删除:等所有传输完成再删除,减少风险 |
-n, --dry-run |
模拟运行,不实际传输,测试用 |
-u, --update |
跳过目标端更新的文件(基于时间戳) |
--ignore-existing |
跳过目标端已存在的文件(不管时间戳) |
-c, --checksum |
根据校验和(而非大小+时间)判断文件是否改变,更精确但更慢 |
--max-size / --min-size |
按文件大小过滤 |
--exclude / --include |
文件过滤模式 |
--exclude-from=FILE |
从文件读取排除模式 |
-b, --backup |
目标端重命名已存在文件作为备份 |
--suffix=SUFFIX |
备份文件后缀,默认 ~ |
--link-dest=DIR |
硬链接目标目录中的不变文件,实现增量备份快照 |
-S, --sparse |
高效处理稀疏文件(如虚拟机磁盘) |
-H, --hard-links |
保留硬链接关系,否则可能变成单独文件 |
--bwlimit=RATE |
限速,单位KB/s(如 --bwlimit=5000) |
--partial |
保留不完整传输文件,便于断点续传 |
--partial-dir=DIR |
将部分传输文件存入指定目录,更加整洁 |
--timeout=SECS |
设置 I/O 超时 |
--contimeout=SECS |
连接超时 |
四、实战技巧详解
1. 增量备份“快照”——--link-dest 硬链接妙用
利用文件系统的硬链接,可实现类似 Time Machine 的备份,每天只占用变化文件的增量空间:
rsync -avh --delete --link-dest=/backup/latest /data/ /backup/$(date +%F)/
rm -f /backup/latest
ln -s /backup/$(date +%F) /backup/latest
- 昨天备份的目录作为
--link-dest,新备份中未改动的文件硬链接到昨天,仅变化文件写入新数据。 - 每个备份目录看似完整,实际多份共享相同 inode 磁盘块。
2. 文件排除/包含模式
- 排除特定目录:
--exclude='cache/' --exclude='*.tmp' - 混合包含/排除:先包含再排除
rsync -av --include='*.txt' --include='*.log' --exclude='*' src/ dest/ - 模式规则:从第一个匹配的模式决定文件命运;
+包含,-排除。 - 从文件读取:
--include-from=include.txt --exclude-from=exclude.txt
3. 安全的删除镜像
生产环境常需让目标与源完全一致。为了避免误删,建议:
- 先用
--dry-run或-n查看会删除哪些文件。 - 使用
--delete-delay让删除发生在传输结束,避免因传输中断导致目标不完整时误删。 - 结合
--backup把被删除的文件移到备份目录:rsync -av --delete --backup --backup-dir=/backup/deleted src/ dest/
4. 断点续传与传输限制
- 大文件传输加
-P(--partial --progress),中断后再次执行同一命令,可基于已传输的部分继续,不必重头开始。 - 带宽控制:
--bwlimit=2000限制为 2MB/s,避免占满网络。 - 丢弃过时传输残留:用
--partial-dir=/tmp/.rsync-partial隐藏起来。
5. rsync 守护进程配置(rsyncd.conf)
典型模块定义:
[backup]
path = /data/backup
comment = Backup Module
read only = no
list = yes
uid = rsync
gid = rsync
auth users = backupuser
secrets file = /etc/rsyncd.secrets
hosts allow = 192.168.1.0/24
hosts deny = *
密码文件格式:backupuser:password,权限设为 600。客户端可使用 rsync -av backupuser@host::backup /local/ 或通过 RSYNC_PASSWORD 环境变量传密码。
守护进程模式相比 SSH,省去系统账号和加密开销,适合局域网高速备份,但默认不加密,敏感数据建议结合 stunnel 或 IPsec。
6. 性能考量
- 更新检测:默认依赖文件大小+修改时间;如果时间戳不可靠(如跨文件系统、git pull 后的文件),加
-c用校验和比较,但会计算整个文件的校验,慢很多。 - 压缩:
-z在慢网络下有效,但若两端均为高速局域网或传输大量已压缩文件(JPEG、zip),压缩反而浪费CPU,可考虑省略。 - 整文件传输:rsync 默认会对本地同步(同一文件系统)使用
--whole-file,因为不需要增量算法。远程同步默认开启增量,可通过--whole-file强制整文件传输,在网络极快、计算资源不足时可能更快。
五、安全最佳实践
- 优先使用 SSH:
rsync -e "ssh -p 2222",数据加密,无需额外开放端口。 - 守护进程限制:
hosts allow/deny限制来源IP。- 强制
uid/gid降权,并用use chroot = yes将访问禁锢在模块路径内。 - 避免使用
root运行 daemon,除非必要。 - 严格设置
secrets file权限(600)。
- 只读模块:需要单向备份时,设
read only = yes。 - 验证完整性:可定期加上
-c做全量校验,确保备份未损坏。
六、常见问题与注意点
- Windows 上的使用:可通过 WSL、cwRsync 或 Git for Windows 携带的 rsync。但注意路径分隔符、权限系统差异,一般建议对纯数据做备份。
- 符号链接:
-a保留符号链接为符号链接,如需跟随链接拷贝实际文件用-L,复制链接指向的对象用--copy-links。 - 硬链接保留:使用
-H,否则两个硬链接文件可能变成两个独立副本,增加空间占用。 - 稀疏文件:如 VM 磁盘镜像,一定加
-S,防止空洞区域被填零传输。 - 文件时间戳与权限保留:需要 root 权限才能完整保留所有者和组,普通用户只能保留自己有权限的属性。
- 原子性:rsync 先把数据写入临时文件(如
.filename.XXXXXX),完成后重命名,目标端几乎不会出现“写了一半”的文件,这是其可靠性的基础。
七、总结
rsync 的强大在于智能增量算法 + 灵活过滤 + 多种传输方式的组合,使其从简单的文件拷贝工具演进为备份同步的标准方案。熟练掌握 --link-dest 快照、--delete 策略和过滤模式,你就可以构建从个人脚本到企业级备份体系的各种应用。
本文来自博客园,作者:ceiloruz,转载请注明原文链接:https://www.cnblogs.com/ceiloruz/p/20204054
浙公网安备 33010602011771号