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

Apache spark Spark资源未在Amazon EMR上完全分配,apache-spark,yarn,emr,Apache Spark,Yarn,Emr,我正试图为一项简单的任务最大限度地利用集群 集群是1+2xm3.xlarge、runnning Spark 1.3.1、Hadoop 2.4、Amazon AMI 3.7 该任务读取文本文件的所有行,并将它们解析为csv 当spark以纱线簇模式提交任务时,我得到以下结果之一: 0执行者:作业无限期等待,直到我手动将其杀死 1执行者:作业正在使用资源,只有1台机器在工作 当我没有在驱动程序上分配足够的内存时发出OOM 我所期望的是: Spark驱动程序在群集主机上运行,所有内存可用,外加2

我正试图为一项简单的任务最大限度地利用集群

集群是1+2xm3.xlarge、runnning Spark 1.3.1、Hadoop 2.4、Amazon AMI 3.7

该任务读取文本文件的所有行,并将它们解析为csv

当spark以纱线簇模式提交任务时,我得到以下结果之一:

  • 0执行者:作业无限期等待,直到我手动将其杀死
  • 1执行者:作业正在使用资源,只有1台机器在工作
  • 当我没有在驱动程序上分配足够的内存时发出OOM
我所期望的是:

  • Spark驱动程序在群集主机上运行,所有内存可用,外加2个执行器,每个执行器9404MB(由install Spark脚本定义)
有时,当我使用1个executor“成功”执行时,克隆和重新启动该步骤的结果是0个executor

我使用以下命令创建了群集:

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
具有一些阶跃变化,包括:

--驱动程序内存8G—驱动程序内核4—num执行器2


使用-x安装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',任务将被分配两个执行器并正确完成

那么,驱动程序内存阻止我获取执行者的任务是怎么回事

驱动程序是否应该与纱线主容器一起在集群的主节点上执行


如何为我的spark job驱动程序提供更多内存?(收集和其他一些有用的操作出现的地方)

问题围绕着火花如何在纱线上工作的预期。当Spark在集群或主节点的部署模式设置为纱线集群的情况下运行时,驱动程序不会在主节点上执行,而是在其中一个从节点上的应用程序主容器中执行。有关更多详细信息,请参阅

我预计现在的情况是,集群无法满足驱动程序的内存需求(请记住,集群实际请求的内存是您要求的内存加上开销),因此永远等待分配驱动程序将运行的应用程序主机或执行器

要为驱动程序提供您请求的内存量,您需要使用额外的从属设备,以便同时为基于群集的驱动程序和执行器提供资源。由于驱动程序上的开销,我怀疑您可能需要使用具有更多内存的实例类型。当您为驱动程序请求8G时,请查看资源管理器日志并验证请求的实际金额


要在主节点上运行驱动程序,部署模式必须是客户端。如果您使用一个步骤调用脚本将驱动程序JAR本地化到主节点上,然后下一个步骤可以调用spark submit set for deployment mode client并引用本地主文件系统上的JAR,则仍然可以使用EMR步骤完成此操作。

最大化集群使用率的解决方案是在在EMR上安装spark,并手动调整执行器内存和内核

这很好地解释了在纱线上运行Spark时如何分配资源

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

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

  • 节点0-主节点(纱线资源管理器)
  • 节点1-节点管理器(容器(驱动程序)+容器(执行器))
  • 节点2-节点管理器(容器(执行器)+容器(执行器))
注意:另一个选项是从主节点0使用
--master warn--deploy mode client
spark submit
。有没有反例这是个坏主意

在我的示例中,我最多可以有3个执行器,每个执行器由2个vCore组成,每个vCore的容量为4736MB,外加一个规格相同的驱动程序

4736内存来自
/home/hadoop/conf/warn site.xml
中定义的
warn.nodemanager.resource.memory mb
的值。在m3.xlarge上,它设置为11520 mb(有关与每个实例类型关联的所有值,请参阅)

然后,我们得到:

(11520-1024)/2(每个节点的执行器)=5248=>5120(四舍五入为256 mb增量,如在warn.scheduler.minimum allocation mb中所定义)

7%*5120=367四舍五入到384(内存开销)在spark 1.4中将变为10%

5120-384=4736

其他有趣的链接:


Michel Lemai的文章是一篇很好的背景阅读,他给出了一个特定集群配置的答案。我已将该逻辑嵌入到电子表格中,该电子表格将显示任何集群的最佳选项。要使用,请填写群集中的节点数、虚拟核心数/节点数和可分配内存/节点数。完成此操作后,工作表将为您提供启动命令的选项,这些命令将充分利用您的集群,以实现每个节点1、2、4和8个执行器的客户机和集群模式。我突出显示了每个节点对应于2个执行器的行,因为这一直是我测试中的最佳选项。您可以随意复制此表或为不同的群集类型添加选项卡


以下是我解决问题的方法:

通过将spark.executor.memory+driver memory设置为低于任何给定主节点的总内存,则纱线能够将主节点和执行器放置在给定节点上。。您牺牲了其他节点上一些丢失的内存,但更重要的是我让CPU运行。以下是一个示例(在r3.8XL上):


那么我希望至少永远有
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