使用 GNU Parallel 并行化 rsync

Man*_*nde 27 linux rhel rsync gnu-parallel

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

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

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/
Run Code Online (Sandbox Code Playgroud)

proj.lst 的内容如下:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *
Run Code Online (Sandbox Code Playgroud)

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

如果我可以rsync并行处理多个进程(使用&,xargsparallel),它将节省我的时间。

我尝试使用以下命令parallel(在cding 到源目录之后),执行时间为 12 分 37 秒:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .
Run Code Online (Sandbox Code Playgroud)

这应该花费的时间少 5 倍,但事实并非如此。我想,我在某个地方出错了。

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

小智 22

我强烈不鼓励任何人使用已接受的答案,更好的解决方案是抓取顶级目录并启动一定数量的 rync 操作。

我有一个很大的 zfs 卷,我的源是一个 cifs 安装。两者都与 10G 链接,并且在某些基准测试中可以使链接饱和。使用 评估性能zpool iostat 1

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

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0
Run Code Online (Sandbox Code Playgroud)

使用单个rsync进程:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这在合成基准测试(水晶盘)中,顺序写入的性能接近 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
Run Code Online (Sandbox Code Playgroud)

它具有相同的性能!

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
Run Code Online (Sandbox Code Playgroud)

作为替代方案,我只是在根文件夹上运行 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
Run Code Online (Sandbox Code Playgroud)

这实际上提高了性能:

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
Run Code Online (Sandbox Code Playgroud)

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


Man*_*nde 21

以下步骤为我完成了这项工作:

  1. 运行第rsync --dry-run一个以获得受影响的文件列表。
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
    --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
Run Code Online (Sandbox Code Playgroud)
  1. 我输入cat transfer.logto的输出parallel以便rsync并行运行 5秒,如下所示:
$ cat /tmp/transfer.log | \
    parallel --will-cite -j 5 rsync -avzm --relative \
      --stats --safe-links --ignore-existing \
      --human-readable {} REMOTE-HOST:/data/ > result.log
Run Code Online (Sandbox Code Playgroud)

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

  • 这将对每个文件进行 rsync。使用 `split` 拆分整个文件列表并将这些文件名提供给并行可能会更有效。然后使用 rsync 的 `--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/ (8认同)
  • 在较新版本的 rsync (3.1.0+) 上,您可以使用 `--info=name` 代替 `-v`,您将只获得文件和目录的名称。如果任何文件中可能包含空格或 shell 元字符,您可能还想使用 --protect-args 来传输 rsync 的“内部”。 (2认同)

Jul*_*ard 20

我个人使用这个简单的:

\ls -1 | parallel rsync -a {} /destination/directory/
Run Code Online (Sandbox Code Playgroud)

只有当您有多个非接近空的目录时,这才有用,否则您最终将几乎每个rsync终止,最后一个单独完成所有工作。

注意前面的反斜杠ls导致别名被跳过。因此,确保输出符合要求。

  • @TomHale 希望它能够穿越时空,击败制作这样一个文件的人…… (2认同)

Ole*_*nge 7

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

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

以下将在 src-dir 到服务器 fooserver 上的 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/{} 
Run Code Online (Sandbox Code Playgroud)

创建的目录可能会以错误的权限结束,并且不会传输较小的文件。最后一次修复那些运行 rsync 的问题:

rsync -Havessh src-dir/ fooserver:/dest-dir/ 
Run Code Online (Sandbox Code Playgroud)

如果您无法推送数据,但需要拉取它们并且文件名为digits.png(例如000000.png),您可以这样做:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/
Run Code Online (Sandbox Code Playgroud)

  • 猫文件| 并行-v ssh fooserver mkdir -p /dest-dir/{//}\; rsync -s -Havessh {} fooserver:/dest-dir/{} (2认同)