背景

当 Flink 流式作业中所有顶点(Vertex)的并行度不一致时,Flink 默认策略的任务部署有时会导致某些 TaskManager 分配到的任务较多,而其他 TaskManager 分配到的任务较少,从而造成任务较多的 TaskManager 资源利用率过高,成为整个作业处理的瓶颈。

任务调度倾斜示例

如图 (a) 所示,给定一个包含两个顶点的 Flink 作业:JobVertex-A(JV-A)和 JobVertex-B(JV-B),并行度分别为 6 和 3,且两个顶点共享同一个 Slot 共享组。在默认任务调度策略下,如图 (b) 所示,各 TaskManager 上的任务分配可能出现较大差异。具体而言,任务最多的 TaskManager 可能承载 4 个任务,而任务最少的 TaskManager 可能只有 2 个任务。因此,承载 4 个任务的 TaskManager 很容易成为整个作业的性能瓶颈。

为此,Flink 提供了基于任务数量的均衡任务调度策略能力。在作业的资源视图中,它旨在使分配到每个 TaskManager 的任务数量尽可能接近,从而改善 TaskManager 之间的资源利用率偏差。

注意:并行度不一致并不意味着必须使用该策略,因为在实际场景中并不总是出现上述问题。


原理

基于任务数量的均衡任务调度策略通过两个阶段完成任务到 TaskManager 的分配:

  • 第一阶段:任务到 Slot 的分配
  • 第二阶段:Slot 到 TaskManager 的分配

本节将通过两个示例来说明该策略在这两个阶段中的简化流程与原理。

第一阶段:任务到 Slot 的分配

以图 (c) 所示的作业为例,该作业包含 5 个 JobVertex,并行度分别为 14423,且它们均属于默认 Slot 共享组。

任务到 Slot 分配原理示意图

在任务到 Slot 的分配阶段,该调度策略执行以下操作:

  • 直接分配最高并行度顶点的任务:将并行度最高的顶点的第 i 个任务直接分配到第 i 个 Slot。即,任务 JV-Bi 直接分配到 sloti,任务 JV-Ci 直接分配到 sloti
  • 轮询分配其余顶点的任务:对于并行度低于最高并行度的其他顶点,在当前 Slot 共享组的各个 Slot 之间以轮询(Round-Robin)方式依次分配任务,直到所有任务分配完毕。

如图 (e) 所示,在基于任务数量的分配策略下,每个 Slot 中的任务数量范围(最大值与最小值之差)为 1,优于默认策略下图 (d) 中范围为 3 的情况。这确保了各 Slot 之间任务数量的更均衡分布。

第二阶段:Slot 到 TaskManager 的分配

如图 (f) 所示,给定一个包含两个顶点 JV-A 和 JV-B 的 Flink 作业,并行度分别为 6 和 3,且两者共享同一个 Slot 共享组。

Slot 到 TaskManager 分配原理示意图

第一阶段分配完成后的结果如图 (g) 所示:Slot0Slot1Slot2 各包含 2 个任务,其余 Slot 各包含 1 个任务。

随后:

  • 该策略提交所有 Slot 请求,并等待当前作业所需的全部 Slot 资源就绪

一旦 Slot 资源就绪:

  • 该策略按 Slot 中包含的任务数量对所有 Slot 请求进行降序排序
  • 随后,依次将每个 Slot 请求分配给当前任务负载最小的 TaskManager,直到所有 Slot 请求分配完毕。

最终分配结果如图 (i) 所示,每个 TaskManager 恰好承载 3 个任务,TaskManager 之间的任务数量差异为 0。相比之下,在默认策略下(如图 (h) 所示),TaskManager 之间的任务数量差异为 2

因此,如果您遇到上述性能瓶颈问题,使用该负载均衡任务调度策略可以提升性能。但如果您没有遇到上述瓶颈,请不要使用该策略,否则可能导致性能下降。


使用方法

您可以通过以下配置项启用均衡任务调度策略:

  • taskmanager.load-balance.modetasks
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐