当前位置: 首页 > 知识库问答 >
问题:

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

隆长卿
2023-03-14

我正在尝试为一个简单的任务最大化集群使用。

集群容量为12×m3。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个执行器“成功”执行时,克隆并重新启动步骤最终会得到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

具有一些阶跃变化,包括:

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

使用-x安装spark脚本将生成以下spark默认值。形态:

$ 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”,则会为该任务分配两个执行器并正确完成。

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

驱动程序应该在集群的主节点上与Yarn主容器一起执行吗?

我如何给我的spark job司机更多的记忆?(收集和一些其他有用的操作发生时)

共有3个答案

柴正祥
2023-03-14

Michel Lemay的帖子是很好的背景阅读,他为1个特定的集群配置给出了答案。我已将该逻辑嵌入到电子表格中,该表格将显示任何集群的最佳选项。要使用,请填写集群中的节点数、虚拟内核/节点数以及可分配内存/节点数。完成此操作后,工作表将为您提供启动命令的选项,这些命令将充分利用您的集群用于两个客户端

https://docs.google.com/spreadsheets/d/1VH7Qly308hoRPu5VoLIg0ceolrzen-nBktRFkXHRrY4/edit?usp=sharing

澹台星剑
2023-03-14

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

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

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

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

邢鸿博
2023-03-14

最大化集群使用率的解决方案是在EMR上安装spark时忘记“-x”参数,并手动调整执行器内存和内核。

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

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

因此,为了最大限度地为驱动程序分配内存,同时最大限度地为执行者分配内存,我应该像这样拆分节点(这张幻灯片在第25页给出了很好的截图):

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

注意:另一个选项是从主节点0使用主纱线-部署模式客户端提交spark。有没有反例这是个坏主意?

在我的例子中,我最多可以有3个2个vcore的执行器,每个vcore 4736 MB,一个具有相同规格的驱动程序。

4736内存来自纱线的值。节点管理器。资源内存mb在主页/hadoop/conf/yarn站点中定义。xml。在m3上。xlarge,将其设置为11520 mb(请参阅此处了解与每个实例类型关联的所有值)

然后,我们得到:

(11520-1024)/2(每个节点的执行器)=5248=

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

5120 - 384 = 4736

其他有趣的链接:

  • Apache Spark:设置执行器实例不会更改执行器
  • 纱线上火花的性能问题
  • http://www.wdong.org/wordpress/blog/2015/01/08/spark-on-yarn-where-have-all-my-memory-gone/
 类似资料:
  • 我在Spark上从事一个项目,最近从使用Spark Standalone切换到使用Mesos进行集群管理。现在,我发现自己对在新系统下提交作业时如何分配资源感到困惑。 在独立模式下,我使用的是这样的东西(以下是Cloudera博客文章中的一些建议: 这是一个集群,其中每台机器有16个内核和大约32 GB RAM。 这样做的好处是,我可以很好地控制运行的执行器的数量以及分配给每个执行器的资源。在上面

  • 我正在使用EMR 4.1.0+spark 1.5.0+YARN来处理大数据。我正试图利用全集群,但有些如何纱没有分配所有的资源。 使用4个C3.8X大型EC2从机节点(每个60.0GB内存和32个核) 根据本文,我在EMR集群中设置了以下参数 yarn.nodemanager.resource.memory-MB->53856 yarn.nodemanager.resource.cpu-vcore

  • 我一直试图在集群模式下通过AWS EMR和YARN运行Spark作业,并且没有设置组合导致该作业最多使用可用总资源的百分之几。 以下是所有节点的典型CPU使用率图表(主节点是从20%开始,然后下降的节点,其他节点都是从节点): 上图是通过以下节点获得的: 使用以下设置运行: 我试着遵循所有典型的建议,包括Spark文档中的建议、AWS EMR文档中的建议以及Cloudera博客上这篇文章中的建议。

  • 我试图在我的API中向一个endpoint发出请求,然而,每次试图访问执行器endpoint都会返回401错误,访问这个资源需要完全身份验证。我只是使用spring security对用户的密码进行加密,然后再将它们存储到数据库中。我已经检查了所有类似的问题,并执行了他们给出的所有解决方案,但仍然没有运气。 securityconfig.java userService.java

  • 尝试构建ARM模板以部署多个VM。但是,模板验证失败,并显示以下错误消息 部署模板验证失败:“资源”为Microsoft。模板中未定义“网络/网络接口/sqlnodeNic”。请看https://aka.ms/arm-template有关用法的详细信息。

  • 我正在使用jersey、jax-rs构建一个web服务应用程序 我在路径“/authenticate”处有一个 jax-rs 资源文件 我有多个带有独立路径的方法,比如“/user”“/test” } 正如对jersey客户端的建议,我使用来自客户端的单个web资源,并使用.path(“/xxx”)从同一web资源构建后续的web资源。 以下是我创建初始 Web 资源的方式 以下是我随后如何使用网