我有一个dataproc群集:
Master -6cors |32G
工作{0-7} -6杆|32G
最大分配:内存:24576,vcores:6
有两个火花流的工作要提交,一个接一个地
首先,我尝试提交默认配置spark.dynamicAllocation.enabled=true
在30%的案例中,我看到第一份工作几乎捕获了所有可用的记忆,第二个工作已经排队并等待了很久以前的资源。(这是一项流式工作,每批都占用了一小部分资源)。
我的第二次尝试是更改动态分配。我提交了具有相同配置的相同两个作业:
spark.dynamicAllocation.enabled=false
spark.executor.memory=12g
spark.executor.cores=3
spark.executor.instances=6
spark.driver.memory=8g
令人惊讶的是,在纱线UI中,我看到了:
7运行容器,具有84G内存分配为第一个作业。
3运行容器,具有36G内存分配和72G保留存储器用于第二个作业
在Spark UI 中,第一个作业有6位执行人和驱动程序,第二个作业的驱动程序和驱动程序
在没有动态分配和相同配置的情况下重试(删除以前的作业并提交相同的作业)后,我得到了完全不同的结果:
5个容器59g内存分配对于作业, 71G保留存储器对于第二个作业。在Spark UI中,我在两种情况下都看到4位执行者和驱动程序。
我有几个问题:
- 如果DynamicAllocation = false ,为什么纱线容器的数量为与执行者人数不同吗?(首先我认为其他纱线容器是驱动程序,但在内存中有所不同。)
- 如果DynamicAllocation = false ,为什么YARN不会由我的我创建容器确切的要求 - 两个作业的6个容器(Spark执行者)。为什么使用相同配置的两次不同尝试导致不同的结果?
- 如果DynamicAllocation = True - 低消耗记忆火花作业如何控制所有纱线资源
谢谢
火花和纱线调度非常令人困惑。我将以相反的顺序回答问题:
3)您不应在火花流动作业中使用动态分配。
问题在于,只要有一项积压的任务要运行,Spark不断向Yarn询问更多执行者。一旦Spark作业获得执行者,它将其保留,直到执行人闲置1分钟(当然可以配置)。在批处理作业中,这是可以的
但是,在流媒体作业中,每个微型批次开始时都有一系列的任务,但是执行者实际上在大多数情况下都是闲置的。因此,流媒体作业将吸引很多不需要的执行者。
为了解决此问题,旧的流api(Dstreams)具有自己的动态分配版本:https://issues.apache.org/jira/browse/browse/spark-12133。此JIRA有更多的背景,即为什么Spark的批处理动态分配算法不适合流式传输。
但是,火花结构化流(可能您正在使用的)不支持动态分配:https://issues.apache.org/jira/browse/browse/spark-24815。
tl; dr spark请求基于其任务积压的执行者,而不是基于使用的内存。
1&2)@vamshi T是正确的。每个纱线应用程序都有一个"应用程序主",该应用程序负责为应用程序请求容器。您的每个Spark作业都有一个应用程序师
您的配置似乎与您在纱线中看到的内容不符,因此不确定那里发生了什么。您有8名工人给纱线24克。对于12G执行者,您应该每个节点有2个执行人,总共16个"插槽"。一个应用程序主 6执行者每个应用程序应为7个容器,因此两个应用程序都应适合16个插槽。
我们配置了应用程序主的内存较少,这就是为什么应用程序的总内存不是12G的干净倍数。
如果您希望两个应用程序同时安排所有执行者,则应设置Spark.executor.intances = 5。
假设您使用的是结构化流,您也可以在同一Spark应用程序中运行两个流媒体作业(从驱动程序上的不同线程提交它们)。
有用的参考:
- 在一个应用程序中运行多个作业:https://spark.apache.org/docs/latest/job-scheduling.html#scheduling-within-an-application
- 动态分配:https://spark.apache.org/docs/latest/job-scheduling.html#dynamic-resource-allocation
- spark-on-yarn:https://spark.apache.org/docs/latest/running-on-yarn.html
我也注意到了我的经验中的类似行为,这就是我观察到的。首先,纱线的资源分配取决于提交作业时集群上的可用资源。当这两个作业几乎同时使用相同的配置提交时,纱线在作业之间平均分配了可用的资源。现在,当您将动态分配给混合物中时,事情变得有些混乱/复杂。现在在下面的情况下:
7运行的容器,具有84G内存分配的第一个作业。 - 您获得了7个容器,因为您请求6位执行人,每个执行人的一个容器,一个额外的一个容器适用于应用程序Master
3运行容器,具有36G内存分配和第二个作业的72G保留存储器 - 第二次工作是在一段时间后提交的,纱线分配了剩余的资源... 2个容器,每个执行人的一个以及用于应用程序主的额外资源。
您的容器永远不会匹配您要求的执行者,并且始终比您要求的执行者数量多,因为您需要一个容器才能运行应用程序Master。
希望回答您问题的一部分。