未在Amazon EMR上完全分配Spark资源

Mic*_*may 20 emr hadoop-yarn apache-spark

我正在尝试最大化群集使用以完成一项简单的任务.

群集是1 + 2 x m3.xlarge,运行Spark 1.3.1,Hadoop 2.4,Amazon AMI 3.7

该任务读取文本文件的所有行并将其解析为csv.

当我将任务作为纱线群集模式提交时,我得到以下结果之一:

  • 0 executor:job无限等待直到我手动杀死它
  • 1执行者:仅使用一台机器工作的资源利用资源
  • 当我没有在驱动程序上分配足够的内存时OOM

我期待的是:

  • Spark驱动程序在集群主服务器上运行,所有可用内存,以及2个执行程序,每个执行程序9404MB(由install-spark脚本定义).

有时,当我使用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
Run Code Online (Sandbox Code Playgroud)

有一些步骤变化,包括:

--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
Run Code Online (Sandbox Code Playgroud)

更新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/
Run Code Online (Sandbox Code Playgroud)

但是,如果我删除'--driver-memory 8G',任务将被分配2个执行程序并正确完成.

那么,驱动程序内存阻止我的任务获取执行程序的问题是什么?

如果驾驶员在集群的主节点上用长丝主容器作为解释的执行一起在这里

如何为我的火花作业驱动程序提供更多内存?(如果出现收集和其他一些有用的操作)

Mic*_*may 22

最大化群集使用的解决方案是在EMR上安装spark并在手动调整执行程序内存和内核时忘记'-x'参数.

这篇文章很好地解释了在YARN上运行Spark时如何完成资源分配.

要记住的一件重要事情是所有执行者必须分配相同的资源!正如我们所说,Spark不支持异构执行程序.(目前正在进行一些支持GPU的工作,但这是另一个主题)

因此,为了在为执行程序最大化内存的同时获得分配给驱动程序的最大内存,我应该像这样拆分我的节点(这个slidehare在第25页提供了很好的截图):

  • 节点0 - 主(纱线资源管理器)
  • 节点1 - NodeManager(容器(驱动程序)+容器(执行程序))
  • 节点2 - NodeManager(容器(执行器)+容器(执行器))

注:另一种选择是,以spark-submit--master yarn --deploy-mode client主节点0是否有任何相反的例子,这是一个坏主意?

在我的例子中,我最多可以拥有2个vcores的3个执行器,每个vron有4736 MB +具有相同规格的驱动程序.

4736内存是从yarn.nodemanager.resource.memory-mb定义的值派生的/home/hadoop/conf/yarn-site.xml.在m3.xlarge上,它设置为11520 mb(有关与每个实例类型关联的所有值,请参见此处)

然后,我们得到:

(11520 - 1024)/ 2(每个节点的执行程序)= 5248 => 5120(向下舍入为yarn.scheduler.minimum-allocation-mb中定义的256 mb增量)

7%*5120 = 367四舍五入到384(内存开销)将变为火花1.4的10%

5120 - 384 = 4736

其他有趣的链接: