Apache spark Spark资源未在Amazon EMR上完全分配
我正试图为一项简单的任务最大限度地利用集群 集群是1+2xm3.xlarge、runnning Spark 1.3.1、Hadoop 2.4、Amazon AMI 3.7 该任务读取文本文件的所有行,并将它们解析为csv 当spark以纱线簇模式提交任务时,我得到以下结果之一: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
- 0执行者:作业无限期等待,直到我手动将其杀死
- 1执行者:作业正在使用资源,只有1台机器在工作
- 当我没有在驱动程序上分配足够的内存时发出OOM
- Spark驱动程序在群集主机上运行,所有内存可用,外加2个执行器,每个执行器9404MB(由install Spark脚本定义)
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-节点管理器(容器(执行器)+容器(执行器))
--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
其他有趣的链接:
以下是我解决问题的方法: 通过将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