我正在使用记录在here中的Amazon特定maximizeResourceAllocation
标志针对Spark运行EMR集群(版本emr-4.2.0)。根据那些文档,“此选项计算核心节点组中某个节点上的执行程序可用的最大计算和内存资源,并使用此信息设置相应的spark-defaults设置”。
我正在使用m3.2xlarge实例作为工作节点运行集群。我正在为YARN主服务器使用单个m3.xlarge-我可以让它运行的最小的m3实例,因为它没有做很多事情。
情况是这样的:当我运行Spark作业时,每个执行器的请求核心数是8。(我只有在配置"yarn.scheduler.capacity.resource-calculator": "org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
之后才得到这个,这实际上不在文档中,但是我离题了)。这似乎是有道理的,因为根据these docs,m3.2xlarge具有8个“ vCPU”。但是,在实际实例本身上,在/etc/hadoop/conf/yarn-site.xml
中,每个节点都配置为将yarn.nodemanager.resource.cpu-vcores
设置为16
。我会(猜测)认为这一定是由于超线程或其他一些硬件幻想造成的。
所以问题是这样的:当我使用maximizeResourceAllocation
时,我得到了Amazon Instance类型拥有的“ vCPU”数量,这似乎只是YARN在该节点上运行的已配置“ VCore”数量的一半。结果,执行程序仅使用实例上实际计算资源的一半。
这是Amazon EMR中的错误吗?其他人也遇到同样的问题吗?我还缺少其他一些不可记录的魔术配置吗?
最佳答案
好吧,经过大量的实验,我能够找到问题所在。我将在这里报告我的发现,以帮助人们将来避免沮丧。
虽然要求的8个内核与YARN知道的16个VCore之间存在差异,但这似乎没有什么区别。 YARN没有使用cgroups或其他任何花哨的东西来实际限制执行程序实际可以使用的CPU数量。
执行器上的“核心”实际上有点用词不当。实际上,执行者一次愿意执行多少个并发任务。本质上可以归结为每个执行器上有多少个线程正在执行“工作”。
设置maximizeResourceAllocation
时,在运行Spark程序时,它会将属性spark.default.parallelism
设置为集群时在集群中的所有非主实例的实例核心(或“ vCPU”)的数量。创建。即使在正常情况下,这也可能太小了;我听说,建议将此值设置为运行作业所需的内核数的4倍。这将有助于确保在任何给定阶段有足够的可用任务来使所有执行器上的CPU保持忙碌状态。
当您具有来自不同火花程序的不同运行的数据时,您的数据(采用RDD或Parquet格式或其他格式)很可能使用不同数量的分区进行保存。运行Spark程序时,请确保在加载时或在CPU密集型任务之前对数据进行重新分区。由于您可以在运行时访问spark.default.parallelism
设置,因此可以方便地重新分配到该编号。
TL; DRmaximizeResourceAllocation
几乎可以为您正确执行所有操作,除了...
您可能希望将spark.default.parallelism
显式设置为希望作业基于“步长”(以EMR表示)/“应用程序”(以YARN表示)运行的实例核心数的4倍,即每次设置...
确保在程序内对数据进行了适当的分区(即需要多个分区),以允许Spark正确并行化数据
关于apache-spark - 使用Amazon的“maximizeResourceAllocation”设置的Spark + EMR并未使用所有核心/vcore,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34003759/