一、为什么跨网段rsync会变成"龟速"?

每次在跨机房同步数据时,看着rsync那个进度条慢悠悠地爬,我都恨不得给它装上火箭推进器。特别是在广域网环境下,明明两边服务器配置都不差,但传输速度就是上不去,这感觉就像开着跑车在乡间小路上堵车。

其实根本原因在于广域网的三个特性:高延迟、低带宽和包丢失。rsync默认配置是为局域网优化的,当遇到跨网段传输时,就像用喝奶茶的细吸管喝一大桶水,怎么使劲都快不起来。

举个例子,我们有个每天需要同步的日志目录,大约50GB:

# 典型慢速同步命令(技术栈:Linux rsync)
rsync -avz /var/log/remote_logs/ user@10.20.30.40:/backup/logs/

# -a 归档模式(保留权限等属性)
# -v 显示详细过程
# -z 启用压缩

这个命令在局域网能跑满千兆,但跨机房可能连10MB/s都不到。

二、性能调优三板斧:并发、压缩与块大小

1. 并发传输:让多个吸管一起工作

rsync的--max-conn参数可以开启多通道传输,相当于同时使用多根吸管:

rsync -avz --max-conn=4 /var/log/remote_logs/ user@10.20.30.40:/backup/logs/

但要注意,不是并发数越多越好。经过测试,在100ms延迟的链路中,4-8个并发通常是最佳值。太多反而会因为TCP拥塞控制导致降速。

2. 压缩的艺术:-z不是万能的

默认的zlib压缩(-z)虽然省带宽,但CPU开销大。我们可以改用更高效的压缩算法:

rsync -av --compress --compress-choice=zstd --compress-level=3 /var/log/remote_logs/ user@10.20.30.40:/backup/logs/

# --compress-choice 指定zstd算法
# --compress-level 3 是性价比最高的级别

实测zstd在level 3时,压缩速度是zlib的3倍,而压缩率只低5%左右,特别适合日志类文本数据。

3. 块大小调整:找到数据包的"黄金比例"

rsync默认的块大小(通常128KB)在广域网可能太小:

rsync -av --block-size=512K /var/log/remote_logs/ user@10.20.30.40:/backup/logs/

通过iperf测试我们找到最佳值:

# 测试网络MTU(技术栈:Linux网络诊断)
ping -M do -s 1472 10.20.30.40  # 测试最大不分包大小
traceroute --mtu 10.20.30.40    # 查看路径MTU

三、进阶优化组合拳

1. 带宽限制的妙用

有时候不限速反而更慢,因为会触发QoS限流:

rsync -avz --bwlimit=10M /var/log/remote_logs/ user@10.20.30.40:/backup/logs/

这个10M不是随便设的,要通过长期监控得出:

# 监控脚本示例(技术栈:Shell)
vnstat -l -i eth0  # 实时流量监控
iftop -N -n -i eth0  # 查看实时带宽使用

2. 预扫描+断点续传

对大目录先做扫描可以避免传输时的元数据开销:

rsync -avz --no-recursive --files-from=<(find /var/log/remote_logs -type f) / user@10.20.30.40:/backup/logs/

3. 终极方案:rsync over ssh隧道

对于特别不稳定的链路,可以先用ssh建立稳定隧道:

# 建立隧道(技术栈:OpenSSH)
ssh -f -N -T -M -L 5000:localhost:873 user@10.20.30.40
# 然后通过本地端口转发使用rsync
rsync -avz --port=5000 /var/log/remote_logs/ localhost::/backup/logs/

四、实战案例与避坑指南

某电商平台的日志同步优化案例:

  1. 原始方案:每天同步耗时4小时
  2. 优化后方案(组合参数):
rsync -av \
  --compress --compress-choice=zstd --compress-level=3 \
  --block-size=512K \
  --max-conn=6 \
  --bwlimit=15M \
  --partial --progress \
  /var/log/remote_logs/ user@10.20.30.40:/backup/logs/

最终将同步时间压缩到45分钟,速度提升5倍以上。

常见坑点:

  1. 不要同时使用-z和--compress,会冲突
  2. 压缩级别超过6时CPU开销剧增
  3. 块大小超过MTU会导致分片重传
  4. 并发数超过8通常收益递减

五、技术选型与替代方案

虽然本文聚焦rsync,但其他工具也有适用场景:

  1. 如果是海量小文件,可以考虑tar打包后传输
  2. 对实时性要求高的场景,可以用lsyncd+rsync组合
  3. 完全不同的技术路线:考虑使用基于UDP的aspera

但rsync仍然是跨网段同步的瑞士军刀,因为:

  1. 内网外网通用
  2. 增量同步效率无可替代
  3. 几乎所有的Linux系统都预装
  4. 经过20多年考验的可靠性

六、总结与最佳实践

经过反复测试,我们总结出跨网段rsync的黄金参数组合:

rsync -aP \
  --compress --compress-choice=zstd --compress-level=3 \
  --block-size=$(($(ping -M do -c 1 -s 1472 10.20.30.40 | grep -oP '(?<=df=)\d+')-28))K \
  --max-conn=$(($(ping -c 5 10.20.30.40 | grep -oP '(?<=time=)\d+' | sort -n | head -1)/20+2)) \
  --bwlimit=$(($(vnstat -i eth0 --oneline | cut -d';' -f11)/1024/2))M \
  /source/ user@remote:/destination/

记住优化三部曲:

  1. 先用ping/traceroute诊断网络基础
  2. 单独测试每个参数的效果
  3. 最后进行组合调优

当你的rsync在广域网上飞起来时,那种成就感就像给老卡车装上了涡轮增压发动机!