Spark ジョブがリソースの割り当て方法を認識していない場合はどうすればよいですか?

数日前、何人かの友人から、spark ジョブのリソース割り当てについて尋ねられました。つまり、ジョブを送信するときに、割り当てるべきリソースの数がわかりません。私の答えは、経験に頼ることです. よくよく考えてみれば、経験に頼ることは言わないことと同じです. いくつかの方法論やアイデアがあるはずです. この記事がありますが、書いたときは本当に書き方がわからなかったので、インターネットで検索して、大物がどのように答えたかを調べました。偶然にも、誰かが 3 年前にこの質問をしたことを本当に知りました。

写真

コメントを読んで自分は理解できた気がしますが、友達が理解できるかどうかわからないので、詳しく説明したほうがいいと思います

写真

まず最初に、spark の公式 Web サイトでハードウェア レベルの提案がいくつか提供されています。最初のリンクは https://spark.apache.org/docs/latest/hardware-provisioning.html です。

ただし、この記事では、アプリケーション レベルで非常に細かい方法でリソースを割り当てる方法については紹介しません。ただし、メモリや CPUなど、関連するいくつかの指示を参照できます。

まず、次のように、spark のこれら 2 つの部分に関連するパラメーターを確認しましょう。

--num-executors/ (SparkSQL の Spark.executor.instances パラメーター)

このパラメーターは、ジョブによって使用されるエグゼキューターの総数を表します

--driver-memory/ (SparkSQL は spark.driver.memory パラメーターで構成されます)

このパラメータは、Driver 側で消費されるメモリを表します. 通常、Driver 側はあまり多くのリソースを消費しないため、多くのリソースを与える必要はありません.

--executor-memory (SparkSQL は spark.executor.memory パラメーターで構成されます)

このパラメータは、各エグゼキュータが占有するメモリを表します

--executor-cores/ (SparkSQL は spark.executor.cores パラメーターで構成されます)

このパラメーターは、エグゼキューターで並列に実行できるタスクの数を表します (並列と同時の違いに注意してください!)

通常、Spark ジョブによって消費される合計メモリ >=(spark.executor.instances)*(spark.exetor.memory);

占有されている CPU の数 >= (spark.executor.instances) * (spark.exector.cores)。

ここで「大なり」が使用されている理由は、AppMaster もリソースを占有するためです。AppMaster に関しては、Yarn 部分の 2 つのパラメーターを確認する必要があります。

yarn.nodemanager.resource.memory-mb

このパラメーターは、nm が Yarn に使用可能な最大メモリーを使用できることを示します。

yarn.nodemanager.resource.cpu-vcores

このパラメーターは、nm が糸に使用できる仮想 CPU の最大数を示します。

一般に、実際の本番環境では、yarn が割り当てることができるリソースの合計が割り当てられている必要があります。個別のスパーク ジョブ キューもあります (ここでも、フェア、FIFO、またはキャパシティのいずれであるかは、糸のスケジューリング モードによって異なります)。

ここで例を挙げて説明しましょう: 合計 6 ノードのベア クラスタがあり、各ノードが 16c 64g で構成されているとします (実際には、各ノードの構成は不均一である可能性があります)。

しかし、すべてのリソースをヤーンに割り当てることは不可能であり、システム運用のために一部を確保する必要があるため、各ノードは 1C と 1G を確保し、極端な方法を取る必要があります。最後に、糸によって割り当てられる各ノードで使用可能なリソースは次のとおりです。

yarn.nodemanager.resource.memory-mb=63g

yarn.nodemanager.resource.cpu-vcores=15

この場合、リソースの合計は all_memory=63*6=378g; all_cpu=6*15=90c です。

各 Executor の並列処理が 5 であると仮定すると、90/5=18 の Executor が必要になりますが、AppMaster 用に 1 つ予約する必要があるため、–num-exectors=17; 合計 18 の Executor が必要であると計算しただけです。合計 6 ノード, 平均して, 各ノードは 3 つのエグゼキュータを開始します, そして 1 つのノードは 63g であるため, 各エグゼキュータは 21g のメモリを占有できます. 注意: 各エグゼキュータはジョブのために 21g をすべて使用するわけではありません, スタック用のリソースも予約します. storage , バッファーのオーバーヘッドは安定性を確保するために使用されます, これはしばしばオフヒープメモリーと呼ばれます. このブロックのオーバーヘッドは spark.executor.memoryOverhead パラメーターによって設定されます, その値 = max(384mb, 0.1*executorMemory) )。したがって、オフヒープ メモリのこの部分 = max(384mb, 0.1*21)~=2g です。次に、ヒープメモリ = 21-2 = 19g です。

要約する表は次のとおりです。

つまり、ジョブを送信するとき、そのパラメーター構成値は次の値を超えることはできません (この例では、すべてのリソースが使用のためにタスクに与えられていると仮定しています!):

--executor-cores / spark.executor.cores = 5--executor-memory / spark.executor.memory = 19--num-executors / spark.executor.instances = 17

ノード数

メモリ/ノード

CPU/ノード

糸は最大量のメモリを割り当てることができます

糸は最大のCPUを割り当てることができます

各エグゼキューターの並列度を想定する

エグゼキュータの総数

実際に働いているエグゼキュータの数

各ノードが開始できるエグゼキューターの数

各エグゼキュータが占有するメモリ

オフヒープ メモリ

実際の作業に使用されるメモリ

6

64g

16C

63g×6=378g

15C*6=90C

5

90℃/5=18

18-1=17

18/6=3

63g/3=21g

最大(384MB,0.1*21g)=2g

21g-2g=19g






9

90c/9=10

10-1=9

10/6~=2

63g/~=2~=37g

最大(384MB,0.1*37g)=3g

37g-3=34g

一部の友人は、なぜ各エグゼキューターの並列処理が 5 に設定されているのか、当然、それを増やすこともできるので、混乱するかもしれません。If you increase the parallelism of each executor, it is equal to Improvement the parallelism capability, which reduce the number of polling tasks. たとえば、100 個のタスクがあり、各エグゼキューターが 20 個のタスクを実行する場合、5 回ポーリングする必要があります。各エグゼキュータが 50 のタスクを設定すると、ポーリングが 2 回必要になります; これにより、各エグゼキュータが保持するメモリが増加します。

実際、前回のフォーラムで言及された評価方法の 1 つは、タスクの数に応じて逆方向に推論することであり、公式には、CPU コアが 2 ~ 3 のタスクを処理するというものです。

写真

次にタスクが100個あると仮定して最大で50c必要か、上記の例で言えば、現時点では各ノードを均等に共有する方法をとるか、少数のノードに処理を集中させるかで決まります。もちろん、採用する方法は、実際に処理するデータの量と計算の複雑なロジックと組み合わせる必要があります (ネットワークの消費や局所的な計算、各ノードの負荷などもここで考慮する必要があるため)。 、共有の方法が通常採用されている場合、各ノードはおそらく8cを使用します。では、各ノードはいくつのエグゼキューターを開始するのでしょうか? 1 つのエグゼキューターを開始するのか、それとも 2 つのエグゼキューターを開始するのか、各エグゼキューターはどのくらいのメモリを占有するのか? 現時点では、コード ロジックがより多く計算するか、より多くキャッシュするかによって異なります。これは、メモリ モデルが関与する場所です. メモリ モデルを知らない人のために, 私の元の記事を参照してください:タングステン オン スパーク メモリ モデルの設計

上記のリソース割り当ては評価されていますが、その後の最適化が必要ないという意味ではありません. そうでなければ、なぜインターネット上にこれほど多くの最適化記事があるのでしょうか? 同時に、チームワーク リソースにも注意を払う必要があります.すべてのリソースをあなたのために使用することはできません。

そのため、評価するリソースの一部を減らす必要があるため、常に調整を行う必要がある場合があります. これが、多くの人がリソースの割り当て方法を尋ねるとき、経験に頼っていると言う理由です!

編集者は、このことに適用する公式は実際にはないと考えています。

リソースを割り当てるためのより良い方法論がある場合、または何かが間違っている場合は、私に連絡して他の友人と共有してください.

他に困ったことがあれば、私に嫌がらせを歓迎します~

参考:

  • スパーク公式サイト

  • https://bbs.csdn.net/topics/392153088

おすすめ

転載: blog.csdn.net/qq_28680977/article/details/122429880