実行中のジョブでインタラクティブにノード数を増減すると、マップの重いジョブを高速化できると直感していますが、ほとんどの作業が削減によって行われる重いジョブの削減には役立ちません。
これについてよくある質問がありますが、実際にはあまりよく説明されていません
実行中のジョブでインタラクティブにノード数を増減すると、マップの重いジョブを高速化できると直感していますが、ほとんどの作業が削減によって行われる重いジョブの削減には役立ちません。
これについてよくある質問がありますが、実際にはあまりよく説明されていません
この質問は、ここに投稿する許可を与えてくれた Christopher Smith によって回答されました。
いつものように... 「場合による」。ほぼ常に期待できることの 1 つは、後でノードを追加しても、最初からノードを使用するほどには役に立ちません。
Hadoop ジョブを作成すると、タスクに分割されます。これらのタスクは事実上「作業の原子」です。Hadoop では、ジョブの作成中にマッパー タスクの数とリデューサー タスクの数を微調整できますが、ジョブが作成されると、ジョブは静的になります。タスクは「スロット」に割り当てられます。従来、各ノードは map タスク用に特定の数のスロットを持ち、reduce タスク用に特定の数のスロットを持つように構成されていましたが、これは微調整できます。一部の新しいバージョンの Hadoop では、スロットを map または reduce タスク用として指定する必要はありません。とにかく、JobTracker は定期的にタスクをスロットに割り当てます。これは動的に行われるため、新しいノードがオンラインになると、タスクを実行するためのスロットが増えるため、ジョブの処理が高速化されます。
これにより、新しいノードの追加の現実を理解するための準備が整います。保留中のタスクよりも多くのスロットを持っているとほとんど成果が得られないという、明らかにアムダールの法則の問題があります (投機的実行が有効になっている場合、Hadoop は同じタスクを多くの異なるノードで実行するようにスケジュールするので、多少は役に立ちます)。予備のリソースがある場合は、より高速なノードで完了します)。そのため、多くの map または reduce タスクを使用してジョブを定義していない場合、ノードを追加してもあまり役に立ちません。もちろん、各タスクにはいくらかのオーバーヘッドがかかるため、極端に高くしたくはありません。そのため、タスク サイズのガイドラインは「実行に 2 ~ 5 分かかるもの」にすることをお勧めします。
もちろん、ノードを動的に追加すると、もう 1 つの欠点があります。それは、ローカルにデータがないことです。明らかに、EMR パイプラインの開始時に、どのノードにもデータが含まれていないので問題ありませんが、多くのジョブで構成された EMR パイプラインがあり、以前のジョブが結果を HDFS に保持している場合は、 JobTracker はシェーピングとタスクの割り当てを優先するため、ノードはデータの適切な局所性を持ちます (これは、パフォーマンスを最大化するための MapReduce 設計全体のコア トリックです)。レデューサー側では、データは他のマップ タスクから取得されるため、動的に追加されたノードは、他のノードと比較して特に不利になることはありません。
したがって、原則として、新しいノードを動的に追加しても、実際には、HDFS から読み取る IO バウンドのマップ タスクに役立つ可能性は低くなります。
を除外する...
Hadoop には、パフォーマンスを最適化するためのさまざまな裏技があります。1 つは、マップ タスクが完了する前/レデューサーが開始する前に、マップ出力データをレデューサーに送信し始めることです。これは明らかに、マッパーが大量のデータを生成するジョブにとって重要な最適化です。Hadoop が転送を開始するタイミングを微調整できます。とにかく、これは、既存のノードがすでに非常に大きなデータの利点を持っている可能性があるため、新しくスピンアップされたノードが不利になる可能性があることを意味します. 明らかに、マッパーが送信した出力が多いほど、不利な点が大きくなります。
それがすべてが実際に機能する方法です。ただし実際には、多くの Hadoop ジョブでは、マッパーが大量のデータを CPU 集約的な方法で処理しますが、レデューサーに出力するデータは比較的少なくなります (または、大量のデータをレデューサーに送信する可能性がありますが、レデューサーは依然として非常に単純です)。したがって、CPU バウンドではありません)。多くの場合、ジョブには少数の (場合によっては 0 の) レデューサー タスクがあるため、余分なノードでさえ役立つ可能性があります。未処理のすべてのレデュース タスクに使用できるレデュース スロットが既にある場合、新しいノードは役に立ちません。新しいノードは、明らかな理由から、CPU バウンドの作業を過度に支援します。削減タスクよりもマップ タスクであることが、人々が通常勝利を収める場所です。マッパーが I/O バウンドでネットワークからデータをプルしている場合、新しいノードを追加するとクラスターの総帯域幅が明らかに増加するため、その点で役立ちますが、マップ タスクが I/O バウンドで HDFS を読み取る場合、最善の方法はより多くの初期ノードがあり、データはすでに HDFS に分散しています。構造化されていないジョブが原因でレデューサーが I/O バウンドになることは珍しくありません。この場合、帯域幅が再び分割されるため、ノードを追加すると非常に役立ちます。
もちろん、そこにも注意点があります。非常に小さなクラスターでは、リデューサーはローカル ノードで実行されているマッパーから大量のデータを読み取る必要があり、ノードを追加すると、より多くのデータがはるかに低速なネットワークを介してプルされるようになります。また、リデューサーがほとんどの時間を、データを送信するすべてのマッパーからのデータ処理を多重化することに費やす場合もあります (これも調整可能ですが)。
このような質問をしている場合は、Amazon が提供する KarmaSphere などを使用して仕事をプロファイリングすることを強くお勧めします。これにより、ボトルネックがどこにあるか、およびパフォーマンスを改善するための最善の戦略は何かをよりよく把握できます。