web-dev-qa-db-ja.com

GNU Parallelを使用してrsyncを並列化します

rsyncスクリプトを使用して、あるホストのデータを別のホストのデータと同期しています。データには、約1.2 TBに寄与する多数の小さなサイズのファイルがあります。

これらのファイルを同期するために、次のように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
...
...
...
- *

テストとして、これらのプロジェクトのうち2つ(8.5GBのデータ)をピックアップし、上記のコマンドを実行しました。順次プロセスであるため、完了するまでに14分58秒かかります。したがって、1.2 TBのデータの場合、数時間かかります。

複数のrsyncプロセスを並行して(&xargsまたはparallelを使用して)できれば、時間を節約できます。

以下のコマンドをparallelで試してみました(ソースディレクトリにcdingした後)。実行に12分37秒かかりました。

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

これは5分の1の時間で済みますが、実際にはかかりませんでした。私はどこかで間違っていると思います。

実行時間を短縮するために複数のrsyncプロセスを実行するにはどうすればよいですか?

20
Mandar Shinde

次の手順は私のために仕事をしました:

  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つのparallelsを並列実行するために、cat transfer.logの出力を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)。

19
Mandar Shinde

誰もが受け入れた回答を使用しないように強くお勧めします。より良い解決策は、トップレベルのディレクトリをクロールし、それに比例した数の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 /秒に近づきます。これは、リンクが飽和していることを意味します。 130MB /秒はあまり良くなく、週末を待つことと2週間待つことの違いです。

そこで、ファイルリストを作成して、もう一度同期を実行しようとしました(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に渡します。ただし、ファイルごとに新しいインスタンスを作成しないでください。

15
Mikhail

私はこのシンプルなものを個人的に使用しています:

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

これは、空ではないディレクトリがいくつかある場合にのみ役立ちます。そうしないと、ほぼすべてのrsyncが終了し、最後のディレクトリがすべての作業を単独で実行することになります。

15
Julien Palard

並列化されたrsyncをテストする方法は次のとおりです。 http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync

rsyncは優れたツールですが、使用可能な帯域幅を使いきらない場合があります。これは、高速接続を介していくつかの大きなファイルをコピーするときに問題になることがよくあります。

次の例では、src-dirの大きなファイルごとに1つのrsyncを開始し、サーバーfooserverのdest-dirに移動します。

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/
5
Ole Tange

常に完全なコマンドを忘れてしまうので、私は常に並列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で見つかったディレクトリ名に置き換えられます。

_/home_に2つのディレクトリがあるとしましょう:_dir1_と_dir2_。 find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ Host:/home/%/)'を実行します。したがって、rsyncコマンドは、次の引数を持つ2つのプロセス(_/home_に2つのディレクトリがあるため、2つのプロセス)として実行されます。

_rsync -a --delete --bwlimit=50000 /home/dir1/ Host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ Host:/home/dir1/
_
1
Sebastjanas

マルチ宛先同期の場合、私は使用しています

parallel rsync -avi /path/to/source ::: Host1: Host2: Host3:

ヒント:すべてのssh接続は、~/.ssh/authorized_keysの公開鍵で確立されます

1
ingopingo