Linux

使用 GNU Parallel 並行化 rsync

  • January 29, 2022

我一直在使用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),那將節省我的時間。

我嘗試使用以下命令parallel(在cding 到源目錄之後),執行需要 12 分 37 秒:

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

這應該減少 5 倍的時間,但事實並非如此。我想,我在某個地方出錯了。

如何執行多個rsync程序以減少執行時間?

以下步驟為我完成了這項工作:

  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秒,我輸入了cat transfer.logto的輸出,如下所示:parallel``rsync
$ 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)。

我強烈勸阻任何人不要使用已接受的答案,更好的解決方案是爬取頂級目錄並啟動成比例的 rsync 操作。

我有一個很大的 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。但不要為每個文件創建新實例。

引用自:https://unix.stackexchange.com/questions/189878