単純なタスクでクラスターの使用を最大化しようとしています。
クラスターは1 + 2 x m3.xlarge、実行中Spark 1.3.1、Hadoop 2.4、Amazon AMI 3.7
タスクはテキストファイルのすべての行を読み取り、csvとして解析します。
ヤーンクラスターモードとしてタスクをスパークサブミットすると、次のいずれかの結果が表示されます。
私が期待していたこと:
場合によっては、1つのエグゼキューターで「成功した」実行が行われると、ステップの複製と再始動が0エグゼキューターで終了することがあります。
次のコマンドを使用してクラスターを作成しました。
aws emr --region us-east-1 create-cluster --name "Spark Test"
--ec2-attributes KeyName=mykey
--AMI-version 3.7.0
--use-default-roles
--instance-type m3.xlarge
--instance-count 3
--log-uri s3://mybucket/logs/
--bootstrap-actions Path=s3://support.elasticmapreduce/spark/install-spark,Args=["-x"]
--steps Name=Sample,Jar=s3://elasticmapreduce/libs/script-runner/script-runner.jar,Args=[/home/hadoop/spark/bin/spark-submit,--master,yarn,--deploy-mode,cluster,--class,my.sample.spark.Sample,s3://mybucket/test/sample_2.10-1.0.0-SNAPSHOT-shaded.jar,s3://mybucket/data/],ActionOnFailure=CONTINUE
以下を含むいくつかのステップのバリエーション:
--driver-memory 8G --driver-cores 4 --num-executors 2
-xを指定したinstall-sparkスクリプトは、次のspark-defaults.confを生成します。
$ cat spark-defaults.conf
spark.eventLog.enabled false
spark.executor.extraJavaOptions -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxHeapFreeRatio=70
spark.driver.extraJavaOptions -Dspark.driver.log.level=INFO
spark.executor.instances 2
spark.executor.cores 4
spark.executor.memory 9404M
spark.default.parallelism 8
更新1
一般的なJavaWordCountの例でも同じ動作が得られます。
/home/hadoop/spark/bin/spark-submit --verbose --master yarn --deploy-mode cluster --driver-memory 8G --class org.Apache.spark.examples.JavaWordCount /home/hadoop/spark/lib/spark-examples-1.3.1-hadoop2.4.0.jar s3://mybucket/data/
ただし、「-driver-memory 8G」を削除すると、タスクに2つのエグゼキューターが割り当てられ、正しく終了します。
では、ドライバメモリが実行者を取得するタスクを妨げている問題は何ですか?
説明されているように、ドライバはYarnマスターコンテナとともにクラスタのマスターノードで実行する必要があります here ?
sparkジョブドライバーにメモリを追加するにはどうすればよいですか?(収集場所とその他の便利な操作が発生する場所)
クラスターの使用率を最大化するソリューションは、EMRにsparkをインストールするときに「-x」パラメーターを忘れて、エグゼキューターのメモリとコアを手動で調整することです。
この post は、YARNでSparkを実行したときにリソース割り当てがどのように行われるかをかなりよく説明しています。
覚えておかなければならない重要なことの1つは、すべてのエグゼキュータに同じリソースが割り当てられている必要があることです。私たちが言うように、Sparkは異種エグゼキューターをサポートしていません。 (GPUをサポートするために現在いくつかの作業が行われていますが、それは別のトピックです)
したがって、エグゼキュータへのメモリを最大化しながらドライバに割り当てられた最大メモリを取得するには、ノードを次のように分割する必要があります(this slideshare は、25ページの適切なスクリーンショットを提供します)。
注:もう1つのオプションは、マスターノード0からのspark-submit
と--master yarn --deploy-mode client
を使用することです。これが悪い考えである反例はありますか?
私の例では、最大4つの2つのvcoreの3つのエグゼキューターと、それぞれ同じ仕様のドライバーを使用できます。
4736メモリは、yarn.nodemanager.resource.memory-mb
で定義されている/home/hadoop/conf/yarn-site.xml
の値から取得されます。 m3.xlargeでは、11520 mbに設定されます(各インスタンスタイプに関連付けられているすべての値については here を参照)
次に、次のようになります。
(11520-1024)/ 2(ノードあたりのエグゼキューター)= 5248 => 5120(yarn.scheduler.minimum-allocation-mbで定義されているように、256 mbの増分に切り捨てられます)
7%* 5120 = 367は384に切り上げられます(メモリオーバーヘッド)はspark 1.4
5120-384 = 4736
その他の興味深いリンク:
この問題は、SparkがYARNで動作することに対する期待に関係しています。Sparkがクラスターまたはマスターのデプロイメントモードで実行され、ドライバーがyarnクラスターに設定されている場合isnotはマスターノードで実行されますが、いずれかのスレーブノードのApplication Masterコンテナで実行されます。詳細については、 https:// spark.Apache.org/docs/latest/running-on-yarn.html
クラスターがドライバーのメモリ要件を満たせないため(クラスターに実際に要求されたメモリーは、要求されたものとオーバーヘッドであることに注意してください)、ドライバーが実行される場所または執行者。
ドライバーに要求するメモリ量を与えるには、クラスターベースのドライバーとエグゼキューターに同時にリソースを提供するために、追加のスレーブを使用する必要があります。ドライバーのオーバーヘッドがあるため、より多くのメモリを持つインスタンスタイプを使用する必要があるかもしれません。ドライバーに8Gを要求する場合は、リソースマネージャーのログを見て、要求された実際の量を確認してください。
マスターノードでドライバーを実行するには、展開モードがクライアントである必要があります。 1つのステップを使用してドライバーjarをマスターノードにローカライズするスクリプトを呼び出し、次のステップでデプロイメントモードクライアントのspark-submitセットを呼び出し、ローカルマスターファイルでJARを参照する場合、これはEMRステップでも実行できます。システム。
Michel Lemayの投稿は背景を読むのに適しており、特定の1つのクラスター構成について回答を提供しています。そのロジックをスプレッドシートに埋め込んで、どのクラスターにも最適なオプションを示します。使用するには、クラスター内のノード数、仮想コア/ノードの数、および割り当て可能なメモリ/ノードの量を記入します。これを実行した後、シートには、ノードごとに1、2、4、8のエグゼキューターのクライアントモードとクラスターモードの両方でクラスターを完全に利用する起動コマンドのオプションが表示されます。ノードごとに2つのエグゼキューターに対応する行を強調表示しました。これは、これが私のテストで常に最良のオプションであったためです。必要に応じて、このシートをコピーするか、異なるクラスタータイプのタブを追加してください。
https://docs.google.com/spreadsheets/d/1VH7Qly308hoRPu5VoLIg0ceolrzen-nBktRFkXHRrY4/edit?usp=sharing
これが私が問題を回避する方法です:
Spark.executor.memory + driver-memoryを特定のMASTERノードの合計よりも低く設定すると、YARNはマスターとエグゼキューターの両方を特定のノードに配置できます。他のノードで失われたメモリを犠牲にしますが、 CPUを実行していることがより重要です。次に例を示します(r3.8xlarge):
aws emr add-steps --cluster-id j-1234 --steps Type=Spark,Name=foob3,Args=[--conf,spark.memory.fraction=0.95,--conf,spark.memory.storageFraction=0.1,--conf,spark.yarn.executor.memoryOverhead=8000,--conf,spark.executor.memory=200g,--conf,spark.executor.cores=32,--conf,spark.executor.instances=4,--conf,spark.dynamicAllocation.enabled=false,--class,myclass.Foo,--deploy-mode,cluster,--master,yarn,--driver-memory,10g,s3://myjar-1.0-SNAPSHOT.jar],ActionOnFailure=CONTINUE