マルチスレッドファイルのコピー


8

ファイルをネットワーク共有の場所にアップロード(およびファイルに対して他の操作を実行)するために使用されるユーティリティがあります。
ファイルサイズは、数MBから500 MBに変化する傾向があります。
共有の場所にファイルをアップロードするときにマルチスレッドをサポートする必要があるという提案が出ました-バイトチャンクで行う必要はありません-各スレッドは1つのファイルを選択してアップロードを試行する必要があります。

マルチスレッドがこのようなIO操作を高速化できるかどうかは、私にはよくわかりません。私の勘は有効ですか?

確かにこの機能を構築する必要がある場合、ファイルコピーエンジンの設計にはどのようなアプローチが適しているのでしょうか。
robocopyなどのツールを使用することは理にかなっていますか(私はマルチスレッドをサポートする新しいバージョンを読みました)。

編集:遅延といくつかの重要な情報の欠落についての謝罪。
このユーティリティはC#(.Net 2.0)を使用して構築されており、今後のアップデートでも.Netを使用する必要があります(フレームワークのバージョンは制約ではありません)。ユーティリティはユーザーのマシンにインストールされます(WinXPの場合は約20)。ターゲット共有はWin2k3サーバー上にあります。

編集2:TPLを介したファイルのアップロードを実装する簡単なアプリケーションでいくつかのテストを実行することを決定しました。この分析を投稿して、先に進むかどうかを決定します。皆様のご協力に感謝いたします。


1
どのプログラミング言語?Cでは、より慣用的なアプローチselectとして、スレッドの代わりにループを使用して非同期I / Oを使用する方法があります。これを行うには、「コードを裏返しにする」必要があります(ファイルをコピーするコードは、コマンドの簡単なシーケンスではなくなります)が、スレッドの同期について心配する必要はありません。
Joey Adams

おそらく最も簡単で合理的な解決策は、OSにすべてを処理させることですSHFileOperation(FO_COPY)。これにより、Microsoftの人々が合理的であると見なしたすべての最適化が得られます。
MSalters 2011

咳のロボコピーの咳... ロボモジョの
ジェームズ・スネル

回答:


19

これは制限要因に依存しますね。ボトルネックがユーティリティプログラムである場合、複数のコピーを実行するか、より多くのスレッドを使用すると、処理が高速化されます。ネットワークが制限要因である場合は、ユーティリティの複数のインスタンスを追加しても、1秒あたり最大Xバイトで動かなくなるため、役に立ちません。実際には、アプリの2番目のコピーの追加のオーバーヘッドがあるため、害を及ぼす可能性があります。ディスクIOと同じです。コピーできるのは、どちらかのマシンがディスクから読み書きできる速度だけです。それがすでに最大になっている場合は、コピーを追加しても効果がありません。

あなたがする必要があるのは、ボトルネックが何であるかを確認するためにテストし、そこから行くことです。


11

マルチスレッドが役に立たない方法:

クライアントのディスクから同時に読み取る、またはネットワーク経由で同時にデータを送信する複数のスレッドはまったく役に立ちません。クライアントとサーバー間の通信パスが1つしかないため、クライアントは1つのハードディスクからファイルを読み取っている可能性が高いからです。 -drive、ファイルはサーバー上の単一のハードドライブに書き込まれている可能性が高いです。(サーバーにRAIDが搭載されている場合でも、多少の違いはありますが、それほどではありません。)反対に、すでに指摘されているように、読み込まれているファイル間でシークが常に発生するため、パフォーマンスが低下する可能性があります。クライアント上で並列、サーバー上で並列に書き込まれているファイル間の定数シーク。また、ファイルはサーバー上で断片化された状態で格納される可能性があります。

マルチスレッドがどのように役立つか:

ただし、マルチスレッドは別の方法で役立つ場合があります。クライアントに2つのスレッドがあるだけで、ファイルI / OをネットワークI / Oから非同期化できます。これは、クライアントがディスクから次のチャンクを読み取ると同時に、ファイルのチャンクを送信できることを意味します。(サーバーは、ネットワークから次のチャンクを受信すると同時に、ディスク上のファイルのチャンクを同時に書き込むことができます。)これにより、クライアントはネットワークチャネルまたはディスクチャネル(どちらか遅い方)を一度に1つずつ断続的にアクセスするのではなく、飽和状態に保つ傾向があるため、転送プロセスを高速化します。私はそこにあるすべての特殊なファイルコピーユーティリティがそれを行うのに十分賢いはずだと思いますが、私は間違っているかもしれません。

編集:RAIDについて書いたビットを修正しました。

編集:サーバーで2つのスレッドを要求することについてのビットを修正しました。

ここで最も重要なことは(ほとんどどこにでもあるので)測定であると思います。これらのユーティリティの動作を制御することはできないため、スループットを測定して、それがディスクまたはネットワークのアドバタイズされたスループットに近いかどうか(どちらか小さい方)を確認する場合、それが可能な限り最速の方法であるかどうかを知るだけです。 。)


これは素晴らしいアイデアのように見えますが、リモート実行権限(または転送プロトコルが何らかの形でこれを本質的にサポートしている)を持たない限り、ファイル転送ユーティリティが実際にこれを行う方法を理解していません。私はNASからのファイルの巨大な数の定期的な転送を行うためのユーティリティを書くしようとしている、と私は本当に時間を削減する方法を見つける必要があります。
Asad Saeeduddin、2015年

あなたの質問は非常に知覚的であり、それは私の答えの不正確さを示しています。サーバーは通常、サーバーの動作方法により、ディスクアクセスからネットワークI / Oを非同期化しているはずです。サーバーは、クライアントごとに個別のスレッドを生成するのではなく、非同期I / Oを実行する傾向があります。したがって、サーバーについては気にする必要はなく、クライアントについてのみ気にする必要があります。答えを書き直します。
マイクナキス、

@Asadまた、この場合の「サーバー」とは、転送の受信側にあるすべてのマシンを意味することに注意してください。指定されたサーバーの役割を持つマシンである必要はありません。
マイクナキス、

9

プログラムが次のファイルのディレクトリを検索し、ファイルを開いてデータを取得している間、データ転送にギャップが生じる傾向があるため、多くの小さいファイルをコピーする際にマルチスレッドが役立ちます。

マルチスレッドは、クライアントとサーバーの両方にRAIDやSSDなどの並列データストレージがある場合にも役立ちます。キューの深さの数値が大きいほどパフォーマンスが向上します。

それ以外では、それはしばしば物事を遅くします。たとえば、1つのハードドライブで2つのファイルを同時に読み書きすると、強制的にファイル1からファイル2へのシークが繰り返されます。


2

Emmadが述べたように、私はData Expedition、Inc.で働いています。マルチスレッドのファイル転送にはメリットがありますが、パフォーマンスのボトルネックとは何かを注意深く理解する必要があります。

どのネットワークパスにも、データが通過しなければならないハードウェアおよびソフトウェアコンポーネントが少なくとも数十あります。それらの中で最も遅いものがあなたの速度を決定します。ただし、データを移動する方法によって、これらのコンポーネントの動作が変わります。

これに関する多くの背景:http : //www.DataExpedition.com/support/notes/tn0009.html

並列TCPを実行すると、個々のTCP速度がネットワーク、ディスク、およびCPUの容量を大幅に下回る場合に役立ちます。

ただし、毎秒数十メガビットを超えるネットワーク速度を検討している場合は、ハードドライブのスラッシングにより、並列データ転送によりディスクI / Oが指数関数的に減少します。ディスクアクセスがネットワーク容量よりもはるかに遅くなるところまで、すぐに低下する可能性があります。適切な読み取り/書き込みブロックサイズを選択すると役立ちますが、それは特定のハードウェアに依存します。また、Windows XP / 2003のページプールメモリは非常に限られているため、速度が毎秒約200メガビットを超えると不安定になる可能性があることに注意してください。

反対に、ネットワークが毎秒数十メガビットよりも遅い場合、多数の並列TCPを実行すると、個々のセッションの速度が低下し始める、または接続が切断されるまでにレイテンシを押し上げる可能性があります。この場合も、特定のパスと条件でどのレベルの並列処理が機能するかを見つけるための実験の問題です。

そのため、既知のデータパスがあり、時間をかけて並列セッションの数とディスクI / Oを微調整できる場合は、マルチスレッドファイルコピーが役立ちます。ただし、状況が変化するたびに再調整する必要があり、過度に調整すると混乱を招く可能性があります。そのため、TCPを回避するのと同じように、独自のソフトウェアで並列転送を回避することにしました。


1

言われたことに加えて、以下を考慮してください。-チャンクを作成するタスクがクライアント上にあり、サーバー上に別のチャンクが1つのファイルとして再びそれらを元に戻す必要があります。これにはいくつかの作業が必要です。

  • 小さなチャンクの良い点は、大きなファイルをすべて送信する代わりに、プロセスが失敗した場合にファイルの一部を再送信できることです。

  • クライアントとサーバー間の「より大きなパイプ」をリクエストすることを検討してください。

  • 送信する前に大きなファイルを圧縮することを検討してください(マルチメディアファイルは既に圧縮されている場合があるため、これが役立つかどうかはわかりません)。

  • 次のような商用ファイル転送ユーティリティの使用を検討してください。

DataExp


0

1つの大きなファイルについて話している場合、マルチスレッド化は実際には役に立ちません。I / Oバウンドになるので、単一のスレッドを使用しても、アップロードの速度が低下することはありません。

ただし、心配するのはリソースの競合です(サーバーも作成していると想定しています)。新しいリクエストも受け入れて処理するスレッドでアップロードを処理している場合、他のリクエストは待機しています。ただし、ソケットからチャンクを読み取ってディスクに書き込んだ後、セレクターキューに延期する限り、問題はありません。


0

単純な方法で提案したことを行うと、スループットが低下します。問題はディスクI / Oであり、ファイルの準備ができていません。

処理するファイルを受け取り、それらをコピーのためにキューに入れ、その後、順次コピーをキュー内の任意の場所で継続する1つのスレッドを使用することをお勧めします。サプライヤスレッドは、ファイルを読み取ってキューに入れる責任があります。このようにして、共有ドライブ上のファイルシステムをスラッシュすることなく、次の準備のためにギャップのあるファイルを一度に1つずつ実行するのではなく、準備と送信を同時に実行します。

おまけに、キューには同期点が1つしかありません。


0

自分で並列アップロードを実装する代わりに、既存のプロトコルとツールを検討することもできます。たとえば、ftpプロトコルとlftpツール(lftpは複数のファイルを並行して転送できます)。

したがって、最初からすべてを実装するのではなく、lftpスクリプトを使用するか、アプリケーションからlftpを制御する方がはるかに簡単で堅牢です。


0

それはすべて、制限要因がどこにあるかに依存します。

マルチスレッドは、伝送に往復遅延やその他のギャップがある場合に役立ち、スレッドはギャップを埋めるのに役立ちます。

マルチスレッドは、ディスクにデータを供給し続けるすべてのスレッドを維持しようとすることで、ディスクを前後にガタガタさせる効果がある場合、害を及ぼす可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.