使用GNU Parallel的Parallelise rsync


18

我一直在使用rsync脚本来将一台主机上的数据与另一台主机上的数据同步。数据中包含许多小型文件,这些文件几乎占了1.2TB。

为了同步这些文件,我一直使用rsync如下命令:

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/

proj.lst的内容如下:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *

作为测试,我选择了其中两个项目(8.5GB数据),并执行了上面的命令。作为一个顺序过程,它需要14分58秒才能完成。因此,对于1.2TB的数据,将需要几个小时。

如果我能多rsync在并行处理(使用&xargsparallel),这将节省我的时间。

我尝试使用下面的命令parallelcd进入源目录后),花了12分37秒执行:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .

这应该花费的时间减少了5倍,但事实并非如此。我认为,我在某处出错。

我如何运行多个rsync进程以减少执行时间?


1
您受到网络带宽的限制吗?磁盘iops?磁盘带宽?
Ole Tange

如果可能,我们将使用总带宽的50%。但是,并行化多个rsyncs是我们的首要任务。
Mandar Shinde

您能否让我们知道您的:网络带宽,磁盘iops,磁盘带宽以及实际使用的带宽?
Ole Tange

实际上,我不知道上述参数。目前,我们可以忽略优化部分。rsync现在,并行处理多个s是主要重点。
Mandar Shinde

如果限制不是CPU,那么并行就毫无意义。它可能甚至会使情况变得更糟(与源或目标磁盘上的磁盘臂移动发生冲突)。
xenoid

Answers:


16

遵循以下步骤为我完成了工作:

  1. 运行第rsync --dry-run一个命令以获取将受到影响的文件列表。
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
    --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
  1. 为了并行运行5 s,我提供了cat transfer.logto 的输出,如下所示:parallelrsync
$ cat /tmp/transfer.log | \
    parallel --will-cite -j 5 rsync -avzm --relative \
      --stats --safe-links --ignore-existing \
      --human-readable {} REMOTE-HOST:/data/ > result.log

在此,--relative选项(link)确保源文件和目标文件中受影响文件的目录结构保持不变(在/data/目录内部),因此该命令必须在源文件夹中运行(例如/data/projects)。


5
这将对每个文件执行rsync。使用拆分整个文件列表split并将这些文件名并行输入会更有效。然后使用rsync's --files-from从每个文件中获取文件名并进行同步。rm备份。* split -l 3000 backup.list备份。ls备份。* | 并行--line-buffer --verbose -j 5 rsync --progress -av --files-from {} / LOCAL / PARENT / PATH / REMOTE_HOST:REMOTE_PATH /
Sandip Bhattacharya

1
第二个rsync命令如何处理result.log中不是文件的行?即receiving file list ... done created directory /data/
Mike D

1
在较新版本的rsync(3.1.0+)上,可以--info=name代替使用-v,而您将仅获得文件和目录的名称。如果任何文件中可能包含空格或外壳程序元字符,您可能也想使用--protect-args来传递“内部” rsync。
猎豹

13

我个人使用这个简单的方法:

ls -1 | parallel rsync -a {} /destination/directory/

只有当您拥有多个非近空目录时,该选项才有用。否则,您将最终拥有几乎每个rsync终结点,最后一个终结点独自完成所有工作。


这很好用-很难知道它是否在做什么,因此-v可以使其更健谈。同样,-j 30 to parallel(即,在rsync命令之前)使其运行30个作业,而不仅仅是每个CPU内核一个作业。
Criggie

12

我会强烈劝阻任何人不要使用公认的答案,更好的解决方案是对顶层目录进行爬网并启动一定比例的rync操作。

我的zfs体积很大,来源是cifs挂载。两者都与10G链接在一起,并且在某些基准测试中可以使链接饱和。使用来评估性能zpool iostat 1

源驱动器的安装方式如下:

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0

使用单个rsync过程:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod

io仪表显示:

StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.62K      0   130M

在综合基准(光盘)中,连续写入的性能接近900 MB / s,这意味着链接已饱和。130MB / s不是很好,等待一个周末和两个星期之间的区别。

因此,我建立了文件列表并尝试再次运行同步(我有64核计算机):

cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log

它具有相同的性能!

StoragePod  29.9T   144T      0  1.63K      0   130M
StoragePod  29.9T   144T      0  1.62K      0   130M
StoragePod  29.9T   144T      0  1.56K      0   129M

作为替代,我只是在根文件夹上运行了rsync:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell

这实际上提高了性能:

StoragePod  30.1T   144T     13  3.66K   112K   343M
StoragePod  30.1T   144T     24  5.11K   184K   469M
StoragePod  30.1T   144T     25  4.30K   196K   373M

总之,在@Sandip Bhattacharya提出的时候,编写一个小脚本来获取目录并进行并行处理。或者,将文件列表传递给rsync。但是不要为每个文件创建新实例。


5

一种经过测试的并行rsync方式是:http ://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync

rsync是一个很棒的工具,但是有时它不会填满可用带宽。通过高速连接复制多个大文件时,这通常是一个问题。

下面的命令将从服务器fooserver上的src-dir到dest-dir的每个大文件启动一个rsync:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{} 

创建的目录可能会以错误的权限结束,并且较小的文件不会被传输。要解决这些问题,请在最后一次运行rsync:

rsync -Havessh src-dir/ fooserver:/dest-dir/ 

如果您无法推送数据,但需要提取数据,并且文件名为digits.png(例如000000.png),则可以执行以下操作:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/

还有其他选择可以避免find吗?
Mandar Shinde

1
限制-maxdepth的查找。
Ole Tange

如果--dry-run在中使用option rsync,我将有一个要传输的文件列表。我可以提供该文件列表以parallel使过程并行化吗?
Mandar Shinde

1
猫文件| 并行-v ssh fooserver mkdir -p / dest-dir / {//} \; rsync -s -Havessh {} fooserver:/ dest-dir / {}
Ole Tange

你能解释一下mkdir -p /dest-dir/{//}\;吗?特别是{//}事情有点混乱。
Mandar Shinde 2015年

1

对于多目的地同步,我正在使用

parallel rsync -avi /path/to/source ::: host1: host2: host3:

提示:所有ssh连接都是使用公共密钥建立的 ~/.ssh/authorized_keys


1

我总是用谷歌搜索并行rsync,因为我总是忘记完整的命令,但是没有任何解决方案对我有用-它包括多个步骤或需要安装parallel。我最终使用这种单线来同步多个文件夹:

find dir/ -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo dir/%/ host:/dir/%/)'

-P 5 是您要产生的进程数量-使用0表示无限(显然不推荐)。

--bwlimit 避免使用所有带宽。

-I %find提供的参数(在中找到目录dir/

$(echo dir/%/ host:/dir/%/)-打印由rsync读取的源和目标目录作为参数。%被替换为由xargs找到的目录名称find

假设我有两个目录中/homedir1dir2。我跑find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ host:/home/%/)'。因此,rsync命令将作为/home具有以下参数的两个进程(两个进程,因为有两个目录)运行:

rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.