Apache Spark:コアの数とエグゼキューターの数


192

YARNでSparkジョブを実行するときのコアの数とエグゼキューターの数の関係を理解し​​ようとしています。

テスト環境は次のとおりです。

  • データノードの数:3
  • データノードマシンの仕様:
    • CPU:Core i7-4790(コア数:4、スレッド数:8)
    • RAM:32GB(8GB x 4)
    • HDD:8TB(2TB x 4)
  • ネットワーク:1 Gb

  • Sparkバージョン:1.0.0

  • Hadoopバージョン:2.4.0(Hortonworks HDP 2.1)

  • Sparkジョブフロー:sc.textFile-> filter-> map-> filter-> mapToPair-> reduceByKey-> map-> saveAsTextFile

  • 入力データ

    • タイプ:単一のテキストファイル
    • サイズ:165​​GB
    • ライン数:454,568,833
  • 出力

    • 2番目のフィルター後の行数:310,640,717
    • 結果ファイルの行数:99,848,268
    • 結果ファイルのサイズ:41GB

ジョブは次の構成で実行されました:

  1. --master yarn-client --executor-memory 19G --executor-cores 7 --num-executors 3 (データノードごとのエグゼキューター、コアと同じだけ使用)

  2. --master yarn-client --executor-memory 19G --executor-cores 4 --num-executors 3 (削減されたコアの数)

  3. --master yarn-client --executor-memory 4G --executor-cores 2 --num-executors 12 (コアが少なく、実行者が多い)

経過時間:

  1. 50分15秒

  2. 55分48秒

  3. 31分23秒

驚いたことに、(3)ははるかに高速でした。
シャッフルするときに実行者間の通信が少なくなるため、(1)はより高速になると思いました。
(1)のコアの数は(3)より少ないですが、2)は十分に機能したため、コアの数は重要な要素ではありません。

(以下はpwilmotの回答の後に追加されました。)

詳細については、パフォーマンスモニターの画面キャプチャを以下に示します。

  • (1)のガングリアデータノードの概要-ジョブは04:37に開始されました。

(1)のガングリアデータノードの概要

  • (3)のガングリアデータノードの概要-ジョブは19:47に開始されました。それ以前のグラフは無視してください。

(3)のガングリアデータノードの概要

グラフはおおまかに2つのセクションに分かれています。

  • 最初:最初からreduceByKeyまで:CPU集中型、ネットワークアクティビティなし
  • 2番目:reduceByKeyの後:CPUが低下し、ネットワークI / Oが実行されます。

グラフが示すように、(1)は指定されたCPUパワーを使用できます。したがって、スレッド数の問題ではない可能性があります。

この結果を説明するには?


2
今、私はGCを疑っています...実際、Spark UIでは、GCに費やされる合計時間は1)で2)よりも長くなります。
zeodtr 14

19Gで3)を試しなかったのはなぜですか?ワーカーを4Gに限定することで、一部のPPLがスポットしているNUMA効果が減少するのでしょうか?つまり、4Gはワークフローに割り当てられた2つのコアの1つに配置されているため、I / O速度の低下が少なく、全体的なパフォーマンスが向上します。それ以外の場合、私は主な質問だと思います:ワーカーで単一のエグゼキューターを使用できるコア/スレッドの数は?(実行者の粒度ではなく、ワーカーのコアの総数のみを指定できます)
Bacon

4
ところで、core / src / main / scala / org / apache / spark / deploy / worker / ExecutorRunner.scalaでコードを確認したところ、1つのexecutor = 1つのワーカーのスレッドのようです。
ベーコン

少し遅れたが、ここでこのトピックに関するClouderaの上のポストです:blog.cloudera.com/blog/2015/03/...
Orelus

1
ちなみに、私はこの情報をclouderaスライドデッキslideshare.net/cloudera/…で見つけました。これは、エクゼキューター、コア、メモリでの意思決定について少し説明しています
Manish Sahni

回答:


58

これをもう少し具体的にするために、可能な限り多くのクラスターを使用するようにSparkアプリを構成する作業例を次に示します。それぞれ16コアと64 GBのメモリを搭載したNodeManagerを実行する6つのノードを持つクラスターを想像してください。NodeManagerの容量、yarn.nodemanager.resource.memory-mbとyarn.nodemanager.resource.cpu-vcoresは、おそらくそれぞれ63 * 1024 = 64512(メガバイト)と15に設定する必要があります。ノードがOSおよびHadoopデーモンを実行するためにいくつかのリソースを必要とするため、リソースの100%をYARNコンテナーに割り当てることは避けます。この場合、これらのシステムプロセスにギガバイトとコアを残します。Cloudera Managerは、これらを考慮し、これらのYARNプロパティを自動的に構成することで役立ちます。

おそらく最初の衝動は、-- num-executors 6 --executor-cores 15 --executor-memory 63Gを使用することです。ただし、次の理由により、これは間違ったアプローチです。

63GB + executorメモリーのオーバーヘッドは、NodeManagerの63GB容量内に収まりません。アプリケーションマスターは、いずれかのノードでコアを使用します。つまり、そのノードには15コアのエグゼキューターのためのスペースがありません。エグゼキューターあたり15コアは、HDFS I / Oスループットの低下につながる可能性があります。

より良いオプションは、-- num-executors 17 --executor-cores 5 --executor-memory 19Gを使用することです。どうして?

この構成により、AMを備えたものを除くすべてのノードに3つのエグゼキューターが作成されます。--executor-memoryは、(ノードあたり63/3のエグゼキューター)= 21. 21 * 0.07 = 1.47として導出されました。21 – 1.47〜19。

説明はClouderaのブログの記事「How-to:Tune Your Apache Spark Jobs(Part 2)」に記載されています。


1
「この構成により、AMを備えたものを除くすべてのノードに3つのエグゼキューターが作成されます。これは、「-executor-cores 5」に関して何を意味しますか?
derek 2017

これは、各エグゼキューターが5つのコアを使用することを意味します。各ノードには3つのエグゼキューターがあり、したがって15コアを使用します。ただし、ノードの1つがジョブのアプリケーションマスターも実行するため、エグゼキューターとして使用中の2つのエグゼキューター、つまり10コアのみをホストできます。
ダボス

うまく説明しました- yarn.scheduler.capacity.resource-calculatorこれはデフォルトの無効に適用されることに注意してください。これは、デフォルトではCPUではなくメモリによってスケジュールされるためです。
YoYo 2018

1
エグゼキューターが増えると、HDFS I / Oスループットが低下する可能性があります。では、HDFSをまったく使用しない場合、エグゼキューターあたり5コア以上を使用できますか?
Darshan

アプリケーションマスターは各ノードで実行されますが。上記のとおり、ジョブを実行するアプリケーションマスターは1つだけです。あれは正しいですか?
Roshan Fernando

15

Sandy Ryzaによると、HDFSの上でSparkアプリを実行すると、

HDFSクライアントが大量の同時スレッドで問題を抱えていることに気づきました。大まかな推測では、エグゼキューターあたり最大5つのタスクで完全な書き込みスループットを達成できるため、エグゼキューターあたりのコア数をその数より少なくすることをお勧めします。

つまり、最初の構成が3番目の構成より遅いのは、HDFS I / Oスループットが悪いためです。


11

私はこれらの設定を自分で試したことがないので、これは単なる推測ですが、この問題を分散システムの通常のコアとスレッドとして考えると、クラスターでは最大12コア(4 * 3マシン)と24スレッドを使用できます(8 * 3台のマシン)。最初の2つの例では、かなりの数のコア(潜在的な計算スペース)をジョブに与えていますが、それらのコアで実行するスレッド(ジョブ)の数が制限されているため、割り当てられた処理能力の多くを使用できません。したがって、割り当てられる計算リソースが多くても、ジョブは遅くなります。

あなたの懸念はシャッフルのステップにあったと述べました-シャッフルのステップでオーバーヘッドを制限することは良いことですが、クラスターの並列化を利用することは一般的にはるかに重要です。極端なケースを考えてみてください-シャッフルがゼロのシングルスレッドプログラム。


回答ありがとうございます。しかし、スレッドの数は主な問題ではないと思います。監視画面のキャプチャを追加しました。グラフが示すように、1)は与えられたのと同じだけのCPUパワーを使用できます。
zeodtr 2014

1
@zeodtr pwilmotは正解です。コアの可能性を最大限に活用するには、最低2〜4のタスクが必要です。つまり、通常、80コアのクラスターには少なくとも1000のパーティションを使用します。
samthebest 2014

@samthebest知りたいのは、1)と3)のパフォーマンスの違いの理由です。Spark UIを見ると、セクション2で21のタスクが並行して実行されます(なぜ今のところ3の場合は24ではなく21のタスクが不明)。ただし、3)のタスクはより高速に実行されます。
zeodtr

10

短い答えtgbaggioは正しいと思います。エグゼキューターのHDFSスループット制限に達した。

ここでの答えは、ここでの推奨事項のいくつかよりも少し単純かもしれません。

私にとっての手がかりは、クラスターネットワークグラフにあります。実行1の場合、使用率は約50 Mバイト/秒で安定しています。実行3の場合、安定した使用率は2倍になり、約100 Mバイト/秒です。

Clouderaのブログの投稿で共有DzOrd、あなたはこの重要な引用符を見ることができます:

HDFSクライアントが大量の同時スレッドで問題を抱えていることに気づきました。大まかな推測では、エグゼキューターあたり最大5つのタスクで完全な書き込みスループットを達成できるため、エグゼキューターあたりのコア数をその数より少なくすることをお勧めします。

それでは、いくつかの計算を行って、それが真の場合に予想されるパフォーマンスを確認します。


実行1:19 GB、7コア、3エグゼキューター

  • 3エグゼキュータx 7スレッド= 21スレッド
  • エグゼキューターあたり7コアの場合、IOはHDFSに制限されると予想されます(最大5コアまで)
  • 実効スループット〜= 3エグゼキューターx 5スレッド= 15スレッド

実行3:4 GB、2コア、12エグゼキューター

  • 2エグゼキュータx 12スレッド= 24スレッド
  • エグゼキューターあたり2コアなので、hdfsスループットは問題ありません
  • 実効スループット〜= 12エグゼキューターx 2スレッド= 24スレッド

ジョブが同時実行性(スレッド数)によって100%制限されている場合。ランタイムはスレッド数と完全に逆相関していると予想されます。

ratio_num_threads = nthread_job1 / nthread_job3 = 15/24 = 0.625
inv_ratio_runtime = 1/(duration_job1 / duration_job3) = 1/(50/31) = 31/50 = 0.62

したがってratio_num_threads ~= inv_ratio_runtime、ネットワークが制限されているようです。

この同じ効果は、実行1と実行2の違いを説明しています。


実行2:19 GB、4コア、3エグゼキューター

  • 3エグゼキュータx 4スレッド= 12スレッド
  • エグゼキューターあたり4コア、HDFSへのIO
  • 実効スループット〜= 3エグゼキューターx 4スレッド= 12スレッド

有効なスレッドの数とランタイムの比較:

ratio_num_threads = nthread_job2 / nthread_job1 = 12/15 = 0.8
inv_ratio_runtime = 1/(duration_job2 / duration_job1) = 1/(55/50) = 50/55 = 0.91

前回の比較ほど完璧ではありませんが、スレッドを失うと、同様のパフォーマンス低下が見られます。

さて、最後のビットです。なぜスレッド数が多いほどパフォーマンスが向上するのですか。CPUの数より多くのスレッド?

並列処理(複数のCPUにデータを分割することによって得られるもの)と同時実行性(単一のCPUで複数のスレッドを使用して作業を行うときに得られるもの)の違いについての適切な説明は、Rob Pikeによるこの素晴らしい投稿で提供されています:同時実行性並列性ではありません

簡単な説明は、Sparkジョブがファイルシステムまたはネットワークと対話している場合、CPUはそれらのインターフェイスとの通信を待機するのに多くの時間を費やし、実際には「作業」に費やさないということです。これらのCPUに一度に複数のタスクを割り当てることで、CPUは待機時間と作業時間を費やし、パフォーマンスが向上します。


1
興味深い説得力のある説明ですが、エクゼキュータには最大スループットを達成するために5つのタスク制限があると思い込んでいるのでしょうか。
Dat Nguyen

したがって、5という数字は思いついたものではありません。IOボトルネックの兆候に気づき、それらのボトルネックがどこから発生しているのかを探りました。
turtlemonvh

8

RStudioのSparklyrパッケージページで入手できる優れたリソースから:

スパークの定義

Sparkの命名法についていくつかの簡単な定義を提供すると便利な場合があります。

ノード:サーバー

ワーカーノード:クラスターの一部であり、Sparkジョブを実行できるサーバー

マスターノード:ワーカーノードを調整するサーバー。

エグゼキュータ:ノード内の一種の仮想マシン。1つのノードに複数のエグゼキューターを含めることができます。

ドライバーノード:Sparkセッションを開始するノード。通常、これはsparklyrが配置されているサーバーです。

Driver(Executor):Driver NodeはExecutorリストにも表示されます。



1

私が考える最初の2つの構成には小さな問題があります。スレッドとコアの概念は次のとおりです。スレッド化の概念は、コアが理想的である場合、そのコアを使用してデータを処理することです。したがって、メモリは最初の2つのケースでは完全には利用されません。この例をベンチマークする場合は、10コアを超えるマシンを選択してください、各マシンにを。次にベンチマークを行います。

ただし、エグゼキューターあたり5つを超えるコアを指定しないでください。I/ Oパフォーマンスにボトルネックが生じます。

したがって、このベンチマーキングを行うのに最適なマシンは、10コアのデータノードである可能性があります。

データノードマシンの仕様:CPU:Core i7-4790(コアの数:10、スレッドの数:20)RAM:32 GB(8 GB x 4)HDD:8 TB(2 TB x 4)


0

主な理由の一つは地域性だと思います。入力ファイルのサイズは165Gで、ファイルの関連ブロックは確実に複数のDataNodeに分散されます。より多くのエグゼキューターがネットワークコピーを回避できます。

executor numをブロック数と等しくなるように設定してみてください。

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