5

JSR 352 - Java プラットフォームのバッチ アプリケーションは、パーティションを使用した並列処理機能を提供します。バッチ ランタイムは、進行を加速するために、異なるパーティションでステップを実行できます。JSR 352 では定義も導入されていthreadsます。次のように、使用するスレッドの数を定義できます。

<step id="Step1">
    <chunk .../>
        <partition>
            <plan partitions="3" threads="2"/>
        </partition>
    </chunk>
</step>

それから私は混乱します: 各スレッドが占有され、CPU バランスが確保されるように、適切なパーティション計画をどのように与えるのですか?

たとえば、To do テーブル A、B、C があり、それらの行はそれぞれ 10 億、100 万、1,000 です。このステップの目的は、これらのエンティティをドキュメントに処理することです。1 つのエンティティが 1 つのドキュメントに移動します。ドキュメント作成の順序は重要ではありません。これらのテーブルのエンティティの CPU 時間は、それぞれ 1 秒、2 秒、5 秒です。スレッド数は 4 です。

テーブル タイプごとに 1 つずつ、3 つのパーティションがある場合、次の1 * 10^9理由により、手順が完了するまでに数秒かかります。

  • パーティション A1 * 10^9 * 1s = 1 * 10^9s、スレッド 2 で実行されます
  • パーティション B1 * 10^6 * 2s = 2 * 10^6s、スレッド 3 で実行されます
  • パーティション C1 * 10^3 * 5s = 5 * 10^3s、スレッド 4 で実行されます

ただし、スレッド 2 が占有されている間、スレッド 3 は から解放され2 * 10^6s、スレッド 4 は から解放され5 * 10^3sます。したがって、明らかに、これは適切な分割計画ではありません。

私の質問は次のとおりです。

  • 上記の例で完成させるより良いパーティション計画はありますか?
  • 私は考えることができます:パーティションは消費するキューであり、スレッドはこのキューを消費しますか?
  • 一般的に、いくつのスレッドを使用できますか / 使用する必要がありますか? それはCPUコアの数と同じですか?
  • 一般に、各スレッドが占有され、CPU バランスが確保されるように、適切なパーティション プランを設定するにはどうすればよいでしょうか。
4

1 に答える 1

3

答え...

上記の例で完了するためのより良いパーティション計画はありますか?

はいあります。回答 4 を参照してください...

私は考えることができます:パーティションは消費するキューであり、スレッドはこのキューを消費しますか?

それがまさに起こることです!

一般的に、いくつのスレッドを使用できますか / 使用する必要がありますか? それはCPUコアの数と同じですか?

場合によります。この質問には多くの視点があります... JSR-352 Specification Viewから、「スレッド」:

このステップのパーティションを実行するスレッドの最大数を指定します。バッチ ランタイムは、要求された数のスレッドが使用可能であることを保証できないことに注意してください。要求された最大数まで可能な限り使用します。これはオプションの属性です。デフォルトはパーティションの数です。

したがって、この観点のみに基づいて、この値を必要なだけ高く設定する必要があります (バッチ ランタイムは、リソースに応じて実際の制限を設定します!)。

バッチ ランタイムの観点から (JSR352 実装) : 適切な実装では、スレッド プールを使用して分割されたステップを実行します。そのため、そのようなプールのサイズが N に固定されている場合、スレッド数をどれだけ大きく設定しても、N 個を超えるパーティションを同時に実行することはありません。

JBeret は、ワイルドフライ サーバーで使用される JSR352 仕様の実装です (これは私が使用した実装です)。Wildfly では、最大 10 スレッドのデフォルトのスレッド プール設定があります。このプールは、分割されたステップ間で共有されるだけでなく、バ​​ッチ ジョブ間でも共有されます。したがって、同時に 2 つのジョブを実行している場合、使用できるスレッドが 2 つ少なくなります。この事実に加えて、パーティション化すると、1 つのスレッドがコーディネーターの役割を果たし、パーティションを他のスレッドに割り当てて結果を待ちます...したがって、パーティション計画で 2 つのスレッドを使用すると言われている場合、実際には 3 つ使用します! (ワーカーとして 2 つ、コーディネーターとして 1 つ)...そして、このすべてのリソース (スレッド) は同じプールから取得されます!!

とにかく、これらすべての重要なことは、使用している JSR325 の実装を調査し、それに応じてセットアップすることです。

ハードウェア ビューから、CPU にはスレッドの最大制限があります。この観点から (経験則として)、「スレッド」の値をそのような値に等しく設定します。

パフォーマンス ビュー から、実行中の作業を分析します。多くのスレッド間で共有リソース (DB など) にアクセスしている場合、スレッドのブロックを引き起こすボトルネックが発生する可能性があります。そのような問題に直面した場合は、「スレッド」の値を下げることを検討する必要があります。

概要で、「スレッド」の値を CPU の最大スレッド制限と同じくらい高く設定します。次に、その値がブロックの問題を引き起こさないかどうかを確認します。その場合は、値を減らします。また、バッチ ランタイムが適切に構成されていること、および必要な数のスレッドを実行できることを確認します。

一般に、各スレッドが占有され、CPU バランスが確保されるように、適切なパーティション プランを設定するにはどうすればよいでしょうか。

静的パーティション計画の使用は避けてください (少なくともあなたの場合)。代わりに、パーティション マッパーを使用します。パーティション マッパーは、javax.batch.api.partition.PartitionMapperインターフェイスを実装し、パーティション プラン (パーティションの数、スレッドの数、各パーティションのプロパティ) をプログラムで定義できるようにするクラスです。したがって、あなたの場合、テーブル(A、B、C)を取り、それらをN個のブロック(N = 1000)に分割します...各ブロックはパーティションになります。タイプ C のパーティションから開始し、エンティティ パーティション (テーブル) 間でラウンド ロビンを実行する必要があります: C0B0A0B1A1...、B999A999A1000...、A999999... このスキームを使用すると、エンティティ C が最初に終了し、1 つのスレッドを開いたままにして、より多くの A および B パーティションを解決します。その後、B が終了し、残りの A パーティションを攻撃するためのリソースが残ります。

この助けを願って...

于 2016-08-01T21:32:28.443 に答える