2016-06-23 51 views
1

我正在使用hadoop集群运行Spark程序,该程序使用纱线调度程序来运行任务。但是,我注意到一个奇怪的行为。纱线有时会杀死一个抱怨内存错误的任务,而如果我在轮次中执行任务,即执行与容器/执行程序相同数量的任务,让它们完成,然后执行下一组任务,它会正常运行意味着任务没有使用比容器中允许的更多的内存。所以,我怀疑纱线试图在一个容器中同时运行多个任务,这就是为什么容器内存不足的原因。有没有办法限制这种行为,并告诉纱线一次只能在一个容器中运行一个任务。限制纱线容器一次只能执行一项任务

+0

您可以添加更多有关您遵循的两种方法的详细信息,例如多少个执行程序和执行程序内存。你如何运行不同的任务组(基于内存?)。同样是在集群上运行的任何其他应用程序使用YARN – Ramzy

+0

基本上在第一种方法中,我只是使用map。在第二种方法中,我每次运行程序多次,任务数量等于执行程序的数量。当我这样做时,它可以正常工作,但是当我简单地使用map并一次运行它时,它就会失败。 – pythonic

回答

2

通常,Spark请求的每个YARN容器都直接对应一个“执行器”,即使YARN可能报告每个容器分配的1个CPU,Spark也会使用spark.executor.cores设置来确定打包到单个执行器中的并发任务数/容器进程。

因此,只需设置spark.executor.cores=1,每个YARN容器一次只能处理一个任务。这可以做为​​配置,如--conf spark.executor.cores=1或者你可以把它放在conf/spark-defaults.conf(在大多数标准的hadoop安装中,这将在/etc/spark/conf/spark-defaults.conf之内)。

请注意,每台机器仍可能有多个YARN容器;如果要每机器一次进一步限制1个任务,则还需要将spark.executor.memory扩展为每台机器上可用的内存量(分配给在该机器上运行的YARN NodeManagers; YARN将拒绝打包所有容器大于你告诉NodeManager它允许使用,即使物理内存较大)。或者你可能会发现你简单地需要将你的机器分割成更大的块,所以你可以使用这个内存设置来找到合适的内存大小,而不会牺牲太多的并行性。

+0

HI @Dennis Huo,为什么不把执行程序设置为1.内核只是处理并行性的执行程序的顶层。 – Ramzy

+0

你的意思是设置'spark.executor.instances = 1'?在这个问题中,YARN指出,为了超过内存限制,YARN会杀死容器,这表明问题在于每个容器内Spark执行环境的*形成,而不是Spark应用程序如何包装到YARN本身。例如,如果spark.executor.cores目前默认配置为16,请求'spark.executor.instances = 1'只会限制应用程序在单个YARN容器中运行,但它仍然会尝试执行16次在任何内存中配置并行的东西 –

+0

在这种情况下,大概pythonic仍然想要利用任何可用的并行机制,并且只需确保每个容器的形状能够正确地适应任务。所以说每台机器有16个核心和16 GB的RAM,但每个任务都需要将4GB加载到内存中。如果spark.executor.instances = 1,spark.executor.cores = 16,spark.executor.memory = 16G,则Spark将抓取1个容器并尝试一次运行16个任务。然后它将被YARN踢出去,因为这16个任务将尝试在该容器中使用总共16 * 4GB == 64GB。 –