Sparkエグゼキュータ番号、コア、エグゼキュータメモリを調整する方法は?


84

上記のパラメータの調整はどこから始めますか。エグゼキュータメモリから始めてエグゼキュータの数を取得しますか、それともコアから始めてエグゼキュータ番号を取得しますか。リンクをたどった。しかし、高レベルのアイデアを得ましたが、どのように、どこから始めて最終的な結論に到達するかはまだわかりません。

回答:


210

次の回答は、タイトルに記載されている3つの主要な側面、つまりエグゼキュータの数、エグゼキュータのメモリ、およびコアの数をカバーしています。ドライバーメモリなど、この回答の時点では取り上げていないパラメーターが他にもある可能性がありますが、近い将来追加したいと思います。

ケース1ハードウェア-6ノード、および各ノード16コア、64 GB RAM

各エグゼキュータはJVMインスタンスです。したがって、1つのノードに複数のエグゼキュータを含めることができます

OSとHadoopデーモンには最初の1コアと1GBが必要なので、15コア、各ノードに63GBのRAMが利用可能です。

コアの数を選択する方法から始めます

Number of cores = Concurrent tasks as executor can run 

So we might think, more concurrent tasks for each executor will give better performance. But research shows that
any application with more than 5 concurrent tasks, would lead to bad show. So stick this to 5.

This number came from the ability of executor and not from how many cores a system has. So the number 5 stays same
even if you have double(32) cores in the CPU.

遺言執行者の数:

Coming back to next step, with 5 as cores per executor, and 15 as total available cores in one Node(CPU) - we come to 
3 executors per node.

So with 6 nodes, and 3 executors per node - we get 18 executors. Out of 18 we need 1 executor (java process) for AM in YARN we get 17 executors

This 17 is the number we give to spark using --num-executors while running from spark-submit shell command

各エグゼキュータのメモリ:

From above step, we have 3 executors  per node. And available RAM is 63 GB

So memory for each executor is 63/3 = 21GB. 

However small overhead memory is also needed to determine the full memory request to YARN for each executor.
Formula for that over head is max(384, .07 * spark.executor.memory)

Calculating that overhead - .07 * 21 (Here 21 is calculated as above 63/3)
                            = 1.47

Since 1.47 GB > 384 MB, the over head is 1.47.
Take the above from each 21 above => 21 - 1.47 ~ 19 GB

So executor memory - 19 GB

最終番号-エグゼキュータ-17、コア5、エグゼキュータメモリ-19 GB


ケース2ハードウェア:同じ6ノード、32コア、64 GB

5は、良好な並行性についても同じです

各ノードのエグゼキュータの数= 32 / 5〜6

したがって、エグゼキュータの総数= 6 * 6ノード= 36です。AM= 35の場合、最終的な数は36-1になります。

エグゼキュータメモリは、ノードごとに6つのエグゼキュータです。63 / 6〜10。オーバーヘッドは.07 * 10 = 700MBです。したがって、オーバーヘッドとして1GBに丸めると、10-1 = 9GBになります。

最終的な数値-エグゼキュータ-35、コア5、エグゼキュータメモリ-9 GB


ケース3

上記のシナリオは、コアの数を固定として受け入れ、エグゼキュータとメモリの数に移動することから始まります。

最初のケースでは、19 GBは必要ないと考え、10 GBで十分である場合、次の数値が表示されます。

コア5各ノードのエグゼキュータの数= 3

この段階では、これは21になり、最初の計算では19になります。ただし、10で問題ないと考えたため(オーバーヘッドが少ないと想定)、ノードあたりのエグゼキュータの数を6に切り替えることはできません(63/10など)。ノードあたり6つのエグゼキュータと5つのコアがある場合、16コアしかない場合、ノードあたり30コアになります。したがって、各エグゼキュータのコア数も変更する必要があります。

もう一度計算すると、

マジックナンバー5は3になります(5以下の任意の数)。したがって、3つのコアと15の使用可能なコアを使用すると、ノードごとに5つのエグゼキューターが得られます。したがって、(5 * 6 -1)= 29エグゼキュータ

したがって、メモリは63 / 5〜12です。オーバーヘッドは12 * .07 = .84です。したがって、エグゼキュータメモリは12-1 GB = 11GBです。

最終的な数は29エグゼキュータ、3コア、エグゼキュータメモリは11GBです


動的割り当て:

注:動的割り振りが有効になっている場合のエグゼキューターの数の上限。つまり、sparkアプリケーションは必要に応じてすべてのリソースを使い果たす可能性があるということです。したがって、他のアプリケーションが実行されていて、タスクを実行するためにコアも必要なクラスターでは、クラスターレベルで実行するようにしてください。つまり、ユーザーアクセスに基づいて、YARNに特定の数のコアを割り当てることができます。したがって、spark_userを作成して、そのユーザーにコア(最小/最大)を与えることができます。これらの制限は、SparkとYARNで実行される他のアプリケーション間で共有するためのものです。

spark.dynamicAllocation.enabled-これがtrueに設定されている場合-エグゼキュータについて言及する必要はありません。理由は以下のとおりです。

spark-submitで指定する静的パラメーター番号は、ジョブ期間全体のものです。ただし、動的割り当てが明らかになると、次のようなさまざまな段階があります。

何から始めるか:

開始するエグゼキュータの初期数(spark.dynamicAllocation.initialExecutors

幾つ :

次に、負荷(保留中のタスク)に基づいて、要求する数。これは、最終的には静的な方法でspark-submitで与える数値になります。したがって、初期エグゼキュータ番号が設定されたら、最小(spark.dynamicAllocation.minExecutors)および最大(spark.dynamicAllocation.maxExecutors)番号に移動します。

いつ尋ねるか与えるか:

新しいエグゼキュータをいつリクエストしますか(spark.dynamicAllocation.schedulerBacklogTimeout)-これだけの期間、保留中のタスクがあります。だからリクエストしてください。各ラウンドで要求されるエグゼキュータの数は、前のラウンドから指数関数的に増加します。たとえば、アプリケーションは最初のラウンドで1つのエグゼキュータを追加し、次のラウンドで2、4、8などのエグゼキュータを追加します。特定の時点で、上記の最大値が明らかになります

いつエグゼキューターを提供しますか(spark.dynamicAllocation.executorIdleTimeout)-

私が何かを逃したならば、私を訂正してください。上記は、私が問題で共有したブログといくつかのオンラインリソースに基づく私の理解です。ありがとうございました。

参照:


2
スタンドアロンモードでは、ノードごとにエグゼキュータが1つしかない場所を読みましたが、それについて何か考えはありますか?私はそれがあなたの答えでカバーされているのを見ません。
jangorecki 2016

2
スタンドアロンクラスターでは、デフォルトで、ワーカーごとに1つのエグゼキューターを取得します。spark.executor.coresで遊ぶ必要があり、ワーカーには複数のエグゼキューターを取得するのに十分なコアがあります。
Ramzy 2016

私のワーカーはセットアップせずに32コアすべてを利用していることがわかったspark.executor.coresので、デフォルトで利用可能なすべてを使用する可能性があります。
jangorecki 2016

ええ、彼らが言うように、コアのデフォルトは無限です。したがって、指定しない限り、sparkは使用可能なすべてのコアを使用できます。
Ramzy 2016

2
@Ramzy動的割り当てを使用する場合でも、Spark.executor.coresを指定して、Sparkが割り当てる各エグゼキューターのサイズを決定する必要があることに注意してください。それ以外の場合、Sparkがアプリケーションに新しいエグゼキューターを割り当てるときはいつでも、必要なのがあと5コアだけであっても、ノード全体(使用可能な場合)を割り当てます。
Dan Markhasin 2016

6

また、ユースケースによって異なりますが、重要な構成パラメーターは次のとおりです。

spark.memory.fraction(実行とストレージに使用される(ヒープスペース-300MB)の割合)http://spark.apache.org/docs/latest/configuration.html#memory-managementから。

キャッシュ/永続化を使用しない場合は、0.1に設定して、プログラムのすべてのメモリを確保します。

キャッシュ/永続化を使用する場合は、次のメモリを確認できます。

sc.getExecutorMemoryStatus.map(a => (a._2._1 - a._2._2)/(1024.0*1024*1024)).sum

HDFSまたはHTTPからデータを読み取りますか?

繰り返しますが、チューニングはユースケースによって異なります。


pysparkを使用したときにmapコマンドがどのように表示されるか知っていますか?sc._jsc.sc()。getExecutorMemoryStatus()を使用してエグゼキュータステータスを取得しましたが、返される内容では何もできません...
Thomas

1
申し訳ありませんが@ThomasDecauxですが、設定するつもりでしたspark.memory.storageFraction=0.1か?AFAIKspark.memory.fractionは、実行とストレージのSpark両方に使用されるメモリの量を決定し(すでに説明しました)、メモリの量(ストレージと実行に使用可能)のみがキャッシュの削除の影響を受けないためです。このリンクを参照してくださいspark.memory.storageFraction
y2k-shubham 2018年

@Thomas私のアプリケーションで、このオプションよりもpersist(StorageLevel.DISK_ONLY)しかない場合は、適切ですか?メモリの一部にのみ影響しますが、ディスクの流出には影響しませんか?
jk1 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.