Apache Flink-是否可以平均分配插槽共享组?

时间:2020-10-30 11:39:40

标签: apache-flink flink-streaming

我们有一个包含操作的管道,分为两个工作负载-Source -> Transform在第一组中,并且是CPU密集型工作负载,它们被放在同一个插槽共享组中,比方说source。还有Sink,这是占用大量RAM的工作量,因为它使用批量上传并在内存中保存大量数据。它已发送到sink插槽共享组。

此外,我们的Source -> Transform工作负载和Sink工作负载具有不同的并行度,因为第一个受源并行度限制。因此,例如,我们的Source -> Transform并行度为50,而Sink并行度等于78。我们有8个TM,每个TM具有16个内核(因此有插槽)。

在这种情况下,对于我们来说,理想的插槽分配策略似乎是为Source -> Transform在每个TM上分配6-7个插槽,其余的-对于Sink导致的CPU-RAM工作负载大致在所有TM上均匀分布。

所以,我想知道是否有一些配置设置可以告诉您平均分配插槽共享组吗?

我仅找到cluster.evenly-spread-out-slots配置参数,但是我不确定它是否实际上平均分配了插槽共享组,不仅是插槽-例如,我同时拥有10个Source -> Transform任务的TM期望6或7。

因此,问题是是否可以告诉Flink在整个群集中平均分配插槽共享组?或者可能还有其他可能性?

Distribute a Flink operator evenly across taskmanagers似乎有点类似于我的问题,但是我主要是在询问插槽共享组的分配。该主题还仅包含使用cluster.evenly-spread-out-slots的建议,但此后可能有所改变。

2 个答案:

答案 0 :(得分:0)

我曾经尝试实现这一点,但是问题是Flink没有提供启用操作员放置的功能。我可以接近的是使用.map(...).slotSharingGroup("name");。正如有关“ Set slot sharing group”的文档所述:

设置操作的插槽共享组。 Flink将投入运营 保持相同的插槽共享组到同一插槽 在其他插槽中没有插槽共享组的操作。这个 可用于隔离插槽。插槽共享组继承自 如果所有输入操作都在同一插槽共享中,则输入操作 组。默认插槽共享组的名称为“默认”, 可以通过调用将操作显式放入该组 slotSharingGroup(“默认”)。

someStream.filter(...)。slotSharingGroup(“ name”);

因此,我根据我拥有的任务插槽的数量以及并行性定义了不同的组。

答案 1 :(得分:0)

我能够找到一种解决方法来平均分配插槽共享组。

从flink 1.9.2开始,甚至引入了任务分发功能,可以通过cluster.evenly-spread-out-slots: trueFLINK-12122 Spread out tasks evenly across all available registered TaskManagers中的flink-conf.yaml来打开它。我试图启用它,但是它没有用。经过深入研究后,我设法找到了开发人员的评论,其中指出该功能仅在独立模式下有效,因为它需要对资源进行初步的预分配-https://issues.apache.org/jira/browse/FLINK-12122?focusedCommentId=17013089&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17013089"

此功能仅保证在计划时注册的所有TM上分散任务。因此,当您使用活动的纱线模式并提交第一份作业时,将不会注册任何TM。因此,Flink将分配第一个容器,将其填满,然后仅分配一个新容器。但是,如果您以独立模式启动Flink,或者在Yarn上完成第一项工作后,仍然注册了一些TM,那么下一项工作将散布开来。

因此,想法是从增加闲置容器超时设置开始a detached yarn session,首先提交一些短暂的假工作,这将简单地从YARN获取所需的资源并完成,然后立即启动主管道,它将分配给已经分配的容器,在这种情况下,cluster.evenly-spread-out-slots: true可以解决问题,并平均分配所有插槽共享组。

因此,总而言之,执行以下操作以获取作业中均匀分布的插槽共享组:

  1. resourcemanager.taskmanager-timeout已增加,允许在为空闲任务管理器释放容器之前提交主要作业。我将其增加到1分钟,这足够了。
  2. 启动yarn-session并动态地向其提交作业。
  3. 调整了主要作业,以便首先调用仅分配资源的假作业。就我而言,这个简单的代码可以在配置主管道之前达到目的:
val env = StreamExecutionEnvironment.getExecutionEnvironment

val job = env
    .fromElements(0)
    .map { x =>
        x * 2
    }
    .setParallelism(parallelismMax)
    .print()

val jobResult = env.execute("Resources pre-allocation job")
println(jobResult)

print("Done. Starting main job!")
相关问题