7

恥ずかしいほど並列の問題があります。それぞれに異なるデータセットを使用して、単一のプログラムの多数のインスタンスを実行します。これを行うには、アプリケーションを毎回異なるパラメータでバッチ キューに何度も送信します。

ただし、多数のジョブがある場合、すべてのジョブが完了するわけではありません。キューの問題ではないようです。すべてのジョブが開始されています。

問題は、実行中のアプリケーションの多数のインスタンスで、多くのジョブがほぼ同時に終了し、そのためすべてのジョブがほぼ同時に並列ファイル システムにデータを書き込もうとすることです。

問題は、プログラムがファイルシステムに書き込むことができず、何らかの方法でクラッシュするか、書き込みを待っているだけで、長時間待機した後にバッチキューシステムがジョブを強制終了することです。(私が問題について収集したものから、すべてではないにしても、完了に失敗したジョブのほとんどは、コア ファイルを残しません)

この問題を回避するためにディスク書き込みをスケジュールする最善の方法は何ですか? 各プロセスが他のプロセスを認識していないという事実を強調するために、私たちのプログラムは恥ずかしいほど並列であることに言及します-何らかの方法で書き込みをスケジュールするために互いに通信することはできません。

私はプログラムのソースコードを持っていますが、私たちはそれを維持または開発していないので、可能であればこれを変更することなく問題を解決したいと考えています (コメントのほとんどはイタリア語です)。

私はこの問題についていくつかの考えを持っています:

  1. 各ジョブは、最初にノードのローカル (スクラッチ) ディスクに書き込みます。次に、どのジョブが完了したかをときどきチェックし、ファイルをローカル ディスクから並列ファイル システムに移動する別のジョブを実行できます。
  2. マスター/スレーブ システムでプログラムの周りに MPI ラッパーを使用します。マスターはジョブのキューを管理し、これらを各スレーブにファームします。スレーブ ラッパーはアプリケーションを実行し、例外をキャッチし (C++ または Java のファイル システム タイムアウトに対してこれを確実に実行できますか?)、ジョブを再実行するようにメッセージをマスターに送り返します。

それまでの間、エラー自体の詳細についてスーパーバイザーをせがむ必要があります。個人的にエラーに遭遇したことはありませんが、非常に多数のデータセットに対してプログラムを使用する必要はありませんでした (まだ)。

参考までに、SGE (Sun GridEngine) バッチ キュー システムを備えた HPC システムで Solaris を実行しています。ファイルシステムは NFS4 で、ストレージサーバーも Solaris を実行しています。HPC ノードとストレージ サーバーは、ファイバー チャネル リンクを介して通信します。

4

3 に答える 3

7

ほとんどの並列ファイル システム、特にスーパーコンピューティング センターの並列ファイル システムは、シリアル ファーム タイプのものではなく、HPC アプリケーションを対象としています。その結果、それらは IOP (1 秒あたりの I/O 操作) ではなく、帯域幅に対して入念に最適化されています。何十億もの小さな小さなファイルを出力するジョブ。ユーザーが自分のデスクトップ上で正常に動作するものを実行し、単純に数百の同時ジョブにスケールアップして IOP のシステムを枯渇させ、自分のジョブと通常は同じシステム上の他のジョブをハングアップさせるのは非常に簡単です。

ここでできる主なことは、集計、集計、集計です。システムに関する詳細情報を入手できるように、実行している場所を教えていただければ幸いです。しかし、いくつかの実証済みの戦略:

  1. ジョブごとに多数のファイルを出力する場合は、出力戦略を変更して、各ジョブが他のすべてのファイルを含む 1 つのファイルを書き出すようにします。ローカル ramdisk がある場合は、それらを ramdisk に書き込んでから、実際のファイルシステムに tar-gz するだけの簡単なことを行うことができます。
  2. asciiではなくバイナリで書きます。ビッグデータは ascii には入りません。バイナリ形式は、書き込みが最大 10 倍速く、やや小さく、ループ内のいくつかの数値ではなく、一度に大きなチャンクを書き込むことができるため、次のようになります。
  3. 大きな書き込みは、小さな書き込みよりも優れています。すべての IO 操作は、ファイル システムで実行する必要があります。小さな書き込みをループするのではなく、少数の大きな書き込みを行います。
  4. 同様に、ファイルのさまざまな部分をさまざまなタイミングで書き込む必要があるような形式で書き込んではいけません。シークは遅くて役に立ちません。
  5. ノードで多くのジョブを実行している場合は、上記と同じラムディスク (またはローカル ディスク) のトリックを使用して、すべてのジョブの出力を tar にまとめ、それらすべてを並列ファイル システムに一度に送信できます。

上記の提案は、並列ファイル システムだけでなく、あらゆる場所のコードの I/O パフォーマンスに役立ちます。IO はどこでも遅く、メモリ内でできることが多く、実行する実際の IO 操作が少ないほど、高速になります。一部のシステムは他のシステムよりも敏感な場合があるため、ラップトップではそれほど気付かないかもしれませんが、役に立ちます.

同様に、多数の小さなファイルよりも大きなファイルの数を減らすと、ディレクトリ リストからファイル システムのバックアップまですべてが高速化されます。それはどこでも良いです。

于 2011-04-11T20:22:49.630 に答える
2

クラッシュの正確な原因がわからないかどうかを判断するのは困難です。ファイルシステムのパフォーマンスに関連するエラーだと思われる場合は、分散ファイルシステムを試すことができます:http: //hadoop.apache.org/common/docs/r0.20.0/hdfs_user_guide.html

マスター/スレーブシステムを実装したい場合は、Hadoopが答えになるかもしれません。

しかし、まず最初に、クラッシュの原因を突き止めようとします...

于 2011-04-11T20:11:17.090 に答える
1

OS は、リソースが不足したときに常に適切に動作するとは限りません。場合によっては、OS が提供できない最初のリソース単位を要求するプロセスを単純に中止することもあります。多くの OS にはファイル ハンドル リソースの制限があり (Windows には数千のハンドル リソースがあり、あなたのような状況ではこれにぶつかる可能性があります)、通常、空きハンドルが見つからないということは、OS が要求プロセスに対して悪いことをすることを意味します。

プログラムの変更を必要とする簡単な解決策の 1 つは、多くのジョブのうち N 個を超えて同時に書き込むことができないことに同意することです。すべてのジョブが参照できる共有セマフォが必要です。ほとんどの OS は、多くの場合、名前付きリソース (!) として 1 つの機能を提供します。ジョブを起動する前に、セマフォを N に初期化します。各書き込みジョブは、ジョブが書き込もうとしているときにセマフォからリソース ユニットを取得し、書き込みが完了したらそのリソース ユニットを解放します。これを実現するためのコードの量は、高度に並列化されたアプリケーションに一度挿入される数行程度です。次に、問題がなくなるまで N を調整します。N==1 で確実に解決でき、おそらくそれよりもはるかに優れたことができます。

于 2011-04-11T20:57:18.120 に答える