Sparkアプリケーションのエグゼキューター、コア、メモリの配布

リソース割り当ては、sparkジョブの実行中に重要な側面です。 正しく設定されていない場合、sparkジョブはクラスターリソース全体を消費し、他のアプリケーションがリソースを飢えさせる可能性があります

Sparkアプリケーシ

パーティション:パーティションは、大規模な分散データセットの小さなチャンクです。 Sparkはパーティションを使用してデータを管理し、executor間で最小限のデータシャッフルでデータ処理を並列化するのに役立ちます。

タスク:タスクは、分散データセットのパーティション上で実行でき、単一のエグゼキュータ上で実行される作業単位です。 並列実行の単位はタスクレベルです。単一のステージで-を持つすべてのタスクは、並列に実行することができます

Executor:executorは、ワーカーノード上のアプリケーションのために起動される単一のJVMプ Executorはタスクを実行し、それらの間でメモリまたはディスクストレージにデータを保持します。 各アプリケーションには独自のエグゼキュータがあります。 単一のノードで複数のエグゼキューターを実行でき、アプリケーションのエグゼキューターは複数のワーカーノードにまたがることができます。 Executorは、Sparkアプリケーションの
期間中は稼働し続け、複数のスレッドでタスクを実行します。 Sparkアプリケーションのエグゼキューターの数は、SparkConf内で指定するか、コマンドラインからflag–num-executorsを使用して指定できます。

Cluster Manager:クラスター上のリソースを取得するための外部サービス(standalone manager、Mesos、YARNなど)。 Sparkは、executorプロセスを取得でき、それらが互いに通信できる限り、cluster managerには依存しません。私たちは主にクラスタマネージャとしてYarnに興味を持っています。 Sparkクラスターはyarn clusterまたはyarn-clientモードで実行できます。

yarn-clientモード–ドライバはクライアントプロセスで実行され、Application MasterはYARNからリソースを要求するためにのみ使

yarn-cluster mode–ドライバはアプリケーションマスタープロセス内で実行され、アプリケーションが初期化されるとクライアントは消えます

コア:コアはCPUの基本的な計算単位であり、CPUは特定の時間にタスクを実行するための一つ以上のコアを持つことができます。 より多くのコアがあればあるほど、より多くの作業が可能になります。 Sparkでは、executorが実行できる並列タスクの数を制御します。H4>Yarnで実行されているSparkアプリケーションのエグゼキューター、コア、およびメモリの配布:

spark-submit–class-num-executors? -エグゼキューター-コア? -エグゼキュータ-メモリ? ….クラスターの–num-executors、–executor-memory、および–execuor-cores spark config paramsを設定する方法を疑問に思ったことはありませんか?

次のリストは、それらを構成する際に留意すべきいくつかの推奨事項をキャプチャします:Hadoop/yarn/OS Deamons:Yarnのようなクラスターマネージャーを使用してsparkアプリケーションを実行すると、NameNode、Secondary NameNode、DataNode、JobTracker、TaskTrackerのようなバックグラウンドで実行されるいくつかの したがって、num-executorsを指定する際には、これらのデーモンがスムーズに実行されるのに十分なコア(ノードあたり約1コア)を脇に置いておく必要があります。

  • Yarn ApplicationMaster(AM): ApplicationMasterは、ResourceManagerからリソースをネゴシエートし、NodeManagersと連携してコンテナとそのリソース消費を実行および監視する責任があります。 Yarnでsparkを実行している場合は、AMが必要とするリソース(〜1024MBと1つのExecutor)を予算化する必要があります。
  • HDFSスループット:HDFSクライアントは、大量の同時スレッドで問題があります。 HDFSは、executorあたり-5タスクで完全な書き込みスループットを達成することが観察されました。 そのため、executorあたりのコア数をその数以下に保つのは良いことです。
  • メモリオーバーヘッド: 次の図は、spark-yarn-memory-usageを示しています。
  • 画像

    この写真からメモを取るための二つのこと:

    1
    2
    3
    4
    5

    Full memory requested to yarn per executor =
    spark-executor-memory + spark.yarn.executor.memoryOverhead.
    spark.yarn.executor.memoryOverhead =
    Max(384MB, 7% of spark.したがって、executorごとに20GBを要求すると、AMは実際に20GB+memoryOverhead=20+7%の20GB=〜23GBのメモリを取得します。

    • メモリが多すぎるexecutorを実行すると、ガベージコレクションが過剰に遅延することがよくあります。
    • 小さなエグゼキュータを実行すると(たとえば、単一のコアと単一のタスクを実行するのに必要な十分なメモリを使用して)、単一のJVMで複数のタスexecutorとコアの詳細をSparkジョブに設定するには、2つの方法があります。 それらは次のとおりです。
      1. Static Allocation–値はspark-submitの一部として与えられます
      2. Dynamic Allocation–値は要件(データのサイズ、必要な計算量)に基づいて取得され、使用後に解放 これは、リソースを他のアプリケーションで再利用するのに役立ちます。

      静的割り当て:

      さて、次の設定を持つ10ノードクラスタを考え、executors-core-memory distributionのさまざまな可能性を分析しましょう:

      1
      2
      3
      4

      **Cluster Config:**
      10 Nodes
      16 cores per Node
      64GB RAM per Node

      First Approach: Tiny executors :

      Tiny executors essentially means one executor per core. 次の表は、このアプローチを使用したspar-config paramsの値を示しています:

      1
      2
      3
      4
      5
      6
      7
      8
      9

      –num-executors = In this approach, we’ll assign one executor per core
      = total-cores-in-cluster
      = num-cores-per-node * total-nodes-in-cluster
      = 16 x 10 = 160
      –executor-cores=1(コアごとに一つのexecutor)
      –executor-memory=executorあたりのメモリ量
      =mem-per-node/num-executors-per-node
      =64GB/16=4GB

    分析:上記で説明したように、コアごとにexecutorが一つだけでは、同じjvmで複数のタスクを実行することはできません。 また、ブロードキャスト変数やアキュムレータなどの共有/キャッシュされた変数は、ノードの各コアで16回複製されます。 また、Hadoop/Yarnデーモンプロセスに十分なメモリオーバーヘッドが残されておらず、ApplicationManagerではカウントされていません。 良くない!

    第二のアプローチ:Fat executors(ノードごとに一つのExecutor):

    Fat executorsは本質的にノードごとに一つのexecutorを意味します。 次の表は、このアプローチを使用したspark-configパラメータの値を示しています:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    –num-executors = In this approach, we’ll assign one executor per node
    = total-nodes-in-cluster
    = 10
    –executor-cores = one executor per node means all ノードのコアは1つのexecutorに割り当てられています
    =total-cores-in-a-node
    =16
    –executor-memory=executorあたりのメモリ量
    =mem-per-node/num-executors-per-node
    =64GB/1=64GB

    分析:エグゼキュータごとに16コアすべてで、applicationmanagerとdaemonプロセスを除いてはカウントされませんが、hdfsスループットは傷つき、過度のガベージ結果 また、良いではありません!

    第三のアプローチ: 脂肪間のバランス(vs)Tiny

    我々は上記で議論した勧告によると:

    • Based on the recommendations mentioned above, Let’s assign 5 core per executors =>--executor-cores = 5 (for good HDFS throughput)
    • Leave 1 core per node for Hadoop/Yarn daemons => Num cores available per node = 16-1 = 15
    • So, Total available of cores in cluster = 15 x 10 = 150
    • Number of available executors = (total cores/num-cores-per-executor) = 150/5 = 30
    • Leaving 1 executor for ApplicationManager =>--num-executors = 29
    • Number of executors per node = 30/10 = 3
    • Memory per executor = 64GB/3=21GB
    • ヒープオーバーヘッドをカウント=7%of21GB=3GB。 だから、実際の--executor-memory=21–3=18GB

    だから、推奨される設定は次のとおりです:29のエグゼキューター、それぞれ18GBのメモリ、それぞれ5コア!!

    分析:この第三のアプローチは、小さなアプローチ対脂肪の間の適切なバランスを発見した方法については明らかです。 言うまでもなく、それは太ったエグゼキュータの並列性と小さなエグゼキュータの最高のスループットを達成しました!!

    動的割り当て

    注:動的割り当てが有効になっている場合のエグゼキューター数の上限は無限大です。 これは、必要に応じてsparkアプリケーションがすべてのリソースを消費できることを示しています。 他のアプリケーションが実行されていて、タスクを実行するためにコアも必要なクラスターでは、クラスターレベルでコアを割り当てる必要があります。

    これは、ユーザーアクセスに基づいてYARNベースのアプリケーションに特定の数のコアを割り当てることができることを意味します。 そのため、spark_userを作成し、そのユーザーにコア(最小/最大)を与えることができます。 これらの制限は、sparkとYARN上で実行される他のアプリケーションとの間で共有するためのものです。

    動的割り当てを理解するために、我々は次のプロパティの知識を持っている必要があります。

    spark。ダイナミックスアロケーション…enabled-これがtrueに設定されている場合、エグゼキュータに言及する必要はありません。 その理由は以下の通りです。

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

    executorsが開始する数は何ですか:

    executorsの初期数(spark。ダイナミックスアロケーション…initialExecutors)で開始するには

    executorの数を動的に制御します。

    次に、負荷(タスク保留)に基づいて、要求するexecutorの数。 これは最終的にspark-submitで静的な方法で与えられる番号になります。 したがって、最初のexecutor番号が設定されると、min(spark.ダイナミックスアロケーション…minExecutors)とmax(spark.ダイナミックスアロケーション…maxExecutors)の数字。

    新しいエグゼキュータを要求するとき、または現在のエグゼキュータを放棄するとき:

    新しいエグゼキュータを要求するとき(spark。ダイナミックスアロケーション…schedulerBacklogTimeout)–これは、このくらいの期間保留中のタスクがあったことを意味します。 そのため、各ラウンドで要求されたエグゼキュータの数に対する要求は、前のラウンドから指数関数的に増加します。 たとえば、アプリケーションは最初のラウンドで1つのエグゼキュータを追加し、その後のラウンドで2、4、8などのエグゼキュータを追加します。 特定の時点で、上記のプロパティmaxが画像に入ります。

    私たちは、executorがsparkを使用して設定されている離れて与えるのですか。ダイナミックスアロケーション…executorIdleTimeout。

    結論として、ジョブの実行時間をより詳細に制御する必要がある場合は、静的な数値が役立つ予期しないデータ量のジョブを監視します。 動的に移動すると、リソースがバックグラウンドで使用され、予期しないボリュームを含むジョブが他のアプリケーションに影響を与える可能性があp>

    https://stackoverflow.com/questions/24622108/apache-spark-the-number-of-cores-vs-the-number-of-executors
    http://spark.apache.org/docs/latest/configuration.html#dynamic-allocation
    http://spark.apache.org/docs/latest/job-scheduling.html#resource-allocation-policy
    https://blog.cloudera.com/blog/2015/03/how-to-tune-your-apache-spark-jobs-part-2/
    http://spark.apache.org/docs/latest/cluster-overview.html

    コメントを残す

    メールアドレスが公開されることはありません。