web-dev-qa-db-ja.com

大きなファイル(〜20 GB)をコピーするためのcpに代わる高速な方法はありますか?

私は大学院生であり、私が働いているグループはLinuxクラスターを維持しています。クラスターの各ノードには独自のローカルディスクがありますが、これらのローカルディスクは比較的小さく、自動バックアップを備えていません。そのため、グループは多くのTBのストレージスペースを持つファイルサーバーを所有しています。私は比較的Linuxの初心者なので、速度、ネットワーキング能力などの点でファイルサーバーの仕様はわかりません。ローカルディスクは、I/Oの点でファイルサーバーよりもかなり速いことが経験からわかっています。 。約十数人がファイルサーバーを使用しています。

cpを使用して〜20 GBのファイルをファイルサーバーからローカルディスクの1つにコピーするには、平均でリアルタイムで約11.5分かかります(timeによると)。 (1)cpは、そのようなコピーのシステム時間は〜45秒しかないことを示しているので、このtime操作はあまり効率的ではありません。 (2)コピー中にtopを調べると、%CPが非常に低い(検査により、おおよそ-10%平均)。

cpを使用してローカルディスク上の1つのフォルダーから同じローカルディスク上の別のフォルダーに同じ〜20 GBのファイルをコピーすると、所要時間は短くなります-リアルタイムで約9分(システム時間は〜51秒) timeに)。そのため、ファイルサーバーはローカルディスクよりもやや遅いように見えますが、おそらくそれほど遅くはありません。ローカルから同じローカルへのコピーが9分より速くないことに驚いています。

ファイルサーバーからローカルディスクの1つに、最大200個の大きなファイル(それぞれ最大20 GB)をコピーする必要があります。だから、私の質問は:Linuxで大きなファイルをコピーするためのcpのより速い代替手段はありますか?(またはcp内に使用できるフラグがあります。コピーを高速化しますか?)このコピー時間をどうにかして少し削ることができたとしても、それは非常に役立ちます。

新しい、より高速なハードウェアディスクを購入することは確かですが、そのようなリソースにアクセスすることはできません。私もシステム管理者ではありません-私は(初心者)ユーザーです-したがって、ディスクの負荷に関する詳細情報にアクセスできません。毎日約12人がファイルサーバーを使用していますが、この特定のノード/ローカルディスクを使用しているのは私だけです。

42
Andrew

コピー中は、%CPUを低くする必要があります。 CPUはディスクコントローラーに「セクターX–YからZのメモリバッファーにデータを取得する」ことを伝えます。次に、それは行って別のことを行います(または、他に何もない場合はスリープします)。データがメモリにある場合、ハードウェアは割り込みをトリガーします。次に、CPUはそれを数回コピーする必要があり、ネットワークカードに「メモリロケーションA、B、およびCでパケットを送信する」と伝えます。次に、他のことをすることに戻ります。

240 Mbpsをプッシュしています。ギガビットLANでは、少なくとも800 Mbpsを実行できる必要がありますが、

  1. これは、ファイルサーバーを使用するすべてのユーザー間で共有されます(スイッチ間の接続など)。
  2. これは、ファイルサーバーが書き込みを処理できる速度によって制限されます。そのディスクI/O帯域幅は、それを使用するすべてのユーザーが共有していることに注意してください。
  3. ファイルサーバーへのアクセス方法(NFS、CIFS(Samba)、AFSなど)を指定していません。ネットワークのマウントを調整する必要があるかもしれませんが、最近の半分では、デフォルトは通常かなりまともです。

ボトルネックを追跡するには、iostat -kx 10が便利なコマンドになります。ローカルハードディスクの使用率が表示されます。これをファイルサーバーで実行できる場合は、ファイルサーバーのビジー状態がわかります。

一般的な解決策は、ボトルネックをスピードアップすることですが、もちろん予算はありません。ただし、より高速なアプローチを見つけることができるいくつかの特殊なケースがあります。

  • ファイルが圧縮可能であり、高速のCPUを使用している場合は、minimal圧縮をその場で実行する方が高速です。 lzopgzip --fastestのようなもの。
  • あちこちでほんの数ビットを変更してからファイルを送り返す場合は、デルタを送るだけの方がはるかに速くなります。残念ながら、rsyncは、デルタを見つけるために両側でファイルを読み取る必要があるため、ここでは実際には役立ちません。代わりに、ファイルを変更するときにデルタを追跡するものが必要です...ここでのほとんどのアプローチはアプリ固有です。しかし、たとえばdevice-mapper(真新しい dm-era target を参照)またはbtrfsを使用して何かを調整できる可能性があります。
  • 同じデータをmultipleマシンにコピーする場合は、udpcastなどを使用して、すべてのマシンに一度に送信できます。

そして、あなたはあなたがシステム管理者ではないことに気づいているので、それはあなたがシステム管理者を持っていることを意味すると思います。または、少なくともファイルサーバーとネットワークの責任者。あなたはおそらく彼/彼女/彼らに尋ねるべきであり、彼らはあなたのセットアップの詳細にはるかに精通しているはずです。システム管理者は、少なくとも期待できる転送速度を通知できるはずです。

53
derobert

これはおそらくより高速な代替手段であり、ネットワークを2日間詰まらせません。1つまたは2つの大きなUSB(USB 3をお持ちの場合)またはFireWireディスクを取り、サーバーに接続してファイルをコピーします。ディスク。ローカルマシンにディスクを運びます。ファイルをマシンにコピーします。

直接SSH(またはSFTP)アクセス権がある場合(システム管理者に問い合わせてください)、scpを圧縮(-C):

scp -C you@server:/path/to/yourfile .

もちろん、これはファイルが圧縮可能である場合にのみ役立ち、暗号化(SSH経由であるため)と圧縮を使用するため、より多くのCPU時間を使用します。

10
Brendan Long

効率の定義は逆です。より効率的な実装はless cpu時間を浪費します。ローカルコピーでは、平均で約74 MB /秒のスループット(読み取り+書き込み)であり、これは単一のハードディスクが取得するのとほぼ同じです。

9
psusi

cp実装はボトルネックではない可能性が高いです。サーバーとクラスターノードの両方でIO iotopを介した使用状況を確認してください。これにより、パフォーマンスを改善できる場所がわかります。

もう1つのヒントは、同じホストから同じデータをコピーしないようにすることです。たとえば、同じ20Gファイルをネットワーク経由でファイルサーバーからすべてのクラスターノードに配布する場合、1サーバーからすべてのクライアントではなく、ピアツーピアの方法でファイルをコピーする方がはるかに速く機能します。実装は少し複雑ですが、直接接続ハブなどのコマンドラインp2pを使用することもできます。

その20Gファイル内で、一部が共通であり、一部がクラスターノード固有である場合は、それを共通部分と特定部分に分割し、共通部分をp2p方式で配布することを検討してください。

8
Michał Šrajer

それらのファイルの性質/内容によって、いくつかの違いが生じる可能性があります。あるコンピューターから別のコンピューターに200ファイル(それぞれ最大20 GB)をコピーする必要があることを理解しました。

これらのファイルが圧縮可能であるか、類似/同一の断片である場合、2つのアプローチがあります。

  • コピーする前にそれらを圧縮するか、Zipが有効になっているコンピューター間にトンネルを作成します。したがって、ネットワークがボトルネックになっている場合は、少し速くなります

  • ファイルが非常に類似している場合、またはファイル間で共通のコンテンツの一部を共有している場合は、 rsync を使用してみてください。ファイルに共通するものを見つけるのにある程度の時間を費やし、それをliterallyにコピーする必要はありません。何が一般的ですか。

edit

これらのファイルを何度もコピーする必要がありますか? (コピーのように->それらのファイルを使用->コンピュータAのファイルの一部を変更->コンピュータBにファイルを再度コピー)

その場合、rsyncは有用です。バージョン間で等しいものを検出しようとし、変更されていないものはコピーしないためです。

そして3番目の方法:上記が正しい場合(ファイルの変更後、すべてのファイルを2番目のコンピューターに再度コピーします)、いくつかのbinary diff最初のコンピューターで変更されたものを2番目のコンピューターで変更するだけです。

8
woliveirajr

暗号化は転送されるデータの量を増加させる可能性があるため、ここでは次のように思います。

2つのシステム間でコピーする場合、ボトルネックはもちろんサーバー間の接続です。

ローカルにコピーする場合は、プロセスがどのように進行するかを見てください。シングルスレッドなので、標準のLinuxユーティリティは次のように使用します。

- for all blocks in a file
      read a block
      write a block

この操作には同時実行性はありません。

速度を上げるには、次のようなものを使用できます。

  buffer -i infile -o outfile -m size-of-shared-memory-default-1MByte

詳細は、buffer(1)のマニュアルページを参照してください。

Bufferコマンドは、コピープロセスを同時に実行する2つのプロセスを設定します。1つは読み取り用、もう1つは書き込み用で、共有メモリバッファーを使用して2つのプロセス間でデータをやり取りします。共有メモリバッファは、未書き込みのデータの上書きや、すでに書き込まれたデータの書き込みを防止する従来の循環バッファです。このプログラムを使用して、ディスクからテープへの転送のコピー時間の約10〜20%を削減しました。

6
mdpc

クラスター全体を同時に更新する必要がある場合は、P2P伝播アルゴリズムを試してみませんか?

https://github.com/lg/murder はTwitterが使用するものです

BTSync もあります。

3
Gui13

同じファイルのセットをローカルコンピューターからサーバーに頻繁にコピーし、あちこちに小さな変更を加える場合。 rsyncまたはDVCS(hgやgitなど)を使用して転送を高速化できます。

gitまたはhgは、デルタを追跡して検出し、それらのデルタのみを転送できます。 gitを使用する場合、両方の側にリポジトリの完全な履歴があるため、デルタを把握するのは非常に簡単です。

rsyncは、ローリングチェックサムアルゴリズムの形式を使用して、反対側の内容を事前に認識せずにデルタを検出します。 rsyncが差分を計算するのにより多くの作業が必要ですが、ファイル履歴全体を保存する必要はありません。

1
Lie Ryan

すべてのファイルを1つのアーカイブにパッケージ化してみてください(圧縮する必要はありません)。私の経験では、その1つのアーカイブをコピーする方が、多数の個別ファイルをコピーするよりも高速です。

1
Munim

bbcp を試してください。私たちの環境でのテストにより、cpには何らかのガバナーが組み込まれていることがわかりました。ガバナーを外すと、サーバーにレッドラインが発生して停止する可能性があるため、注意が必要です。私たちのケースでは、コピーを実行するためにサーバーをオフラインにしていたため、より高速である方が優れていました。これにより、転送時間が数時間短縮されました。

0
James Shewey

コピーする前に、ターゲットファイルが存在しないことを確認してください。

同じホスト上にコピーするだけでも(ネットワークが関与していない場合)、どれだけの時間が費やされるかは意外な場合があります。

ここでの別のcp質問に対する私の回答 を参照してください。要するに、既存のファイルの上書きは、最初にファイルを切り捨てたりリンクを解除してからコピーするよりもはるかに遅くなります。後者は、1.2GBファイルの場合、8倍高速です。

0
Pierre D