共计 2147 个字符,预计需要花费 6 分钟才能阅读完成。
更新记录
2024-01-19
有读者问我,当源端是 Windows 时,执行会报错。
于是着手研究了如何在 Windows 下如何使用 rsync 进行文件传输。
背景
rsync 原生不能支持多线程传输。
如果源端和对端都是同一台服务器,使用 rsync 进行传输时,单线程并不是问题。此时的瓶颈在于 磁盘IO 和CPU。
但是如果源端和对段通过公网传输时,单线程传输可能造成 网络IO 问题。
场景1:
例如有 A、B 两台机器,它们的上行和下行速率均为 300Mbps。
从 A 执行 rsync命令,同步B机器的文件到A,rsync 单线程模式是一次仅传输一个文件,当一个文件传输完毕后,才会执行下一个。
受限于单个TCP连接收到初始窗口和拥塞控制的影响,单线程的任务传输不能跑满 300Mbps的带宽。
场景2:
之前的文章:115网盘制作备份服务器 中介绍过,如何将网盘挂载在 Linux 服务器上。
此时网盘已经映射为了我本地的一个目录。此时如果我想一次性从 网盘目录 复制多个文件 到 Linux 服务器上,数据包是在公网流转。无论使用 rsync 或 cp ,它们都是单线程顺序执行复制,当一个文件传输完毕后,才会复制下一个文件。
实测 115网盘 传输单个文件到 Linux 时,带宽仅有 50Mbps 左右。但是同时传输多个文件时,可以达到约 250Mbps。
了解到有两种方式,可以在此种情况下加快传输速率,充分利用公网带宽。
分别是通过 xargs 或 parellel,一条命令同时创建多个 rsync 进程同步传输。
参考链接:stackoverflow.com/questi…
实践
源端和目的端均为Linux
xargs方式
当复制的源端和对端位于同一台 server:
cd $src_dir ; find . -print0 | xargs -I% -P10 rsync -avuPR % $dest_dir/
从远端复制到本地,且不位于同一台 server :
ssh root@$ip "cd $src_dir ; find . -print0" | xargs -0 -I% -P5 rsync -avuP root@$A_ip:$src_dir/% $dest_dir/
从本地复制到远端,且不位于同一台 server:
cd $src_dir ; find . -print0 | xargs -0 -I% -P5 rsync % -avuPR root@$ip:/$dest_dir
解释如下:
- 管道符前无论使用 ls 或 find,都是为了获取到文件列表。
- find 的
-print0
是指定文件列表中文件的分隔符 - xargs 的
-0
用于指定分隔符 - xargs 的
-P5
用于指定并发运行的进程数 - rsync 的
-R
参数 用于保持相对路径结构
parallel 方式
parallel 命令在某些 Linux 发行版中可能不会自带,需要自行使用包管理器安装。
例如 CentOS7:
yum install parallel -y
当复制的源端和对端位于同一台 server:
cd $src_dir ; find . -print0 | parallel -0 -j 5 rsync -avuPR {} $dest_dir/
从远端复制到本地,且不位于同一台 server :
ssh root@$ip "cd $src_dir ; find . -print0" | parallel -0 -j 5 rsync -avuP root@$A_ip:$src_dir/% $dest_dir/
从本地复制到远端,且不位于同一台 server:
cd $src_dir ; find . -print0 | parallel -0 -j 5 rsync % -avuPR root@$ip:/$dest_dir
解释如下:
- parallel
-0
参数用于指定分隔符 - parallel
-j
参数用于指定并发运行的进程数
源端为 Windows,目的端为Linux
Windows 上并没有原生的 Linux 环境,但是仍可以使用模拟的方式实现兼容 Linux 的操作。例如近期流行的 WSL 或者老牌的 Cygwin。
WSL 配置会更复杂些,这里以 Cygwin 作为范例。站内文章:Win10 安装 Cygwin 模拟 Linux 环境
首先需要在 Cygwin 中安装 rsync 和 openssh。默认安装 Cygwin 没有包含 rsync,且 ssh 并不是标准的 openssh包。
xargs方式
当复制的源端和对端位于同一台 server:
cd $src_dir ; find . -print0 | xargs -I% -P10 rsync -avuPR % $dest_dir/
从远端复制到本地,且不位于同一台 server :
ssh root@$ip "cd $src_dir ; find . -print0" | xargs -0 -I% -P5 rsync -avuP root@$A_ip:$src_dir/% $dest_dir/
从本地复制到远端,且不位于同一台 server:
cd $src_dir; find . -print0 | xargs -0 -I% -P5 rsync % -avuPR root@10.226.24.211:/root/test-1
总结
上述两种方式,都能在公网传输文件时实现多文件并发传输,充分利用公网带宽,
缺陷是 rsync 原生不支持多线程。利用多进程方式传输时 ,-P
参数本身是用于实时打印传输速率,在多文件同时传输时,实时传输速率的输出会走样变形,不太好观测传输进度。