你还不知道的 Flink 调优手段:Task 调度策略
背景当 Flink 流式作业中所有顶点Vertex的并行度不一致时Flink 默认策略的任务部署有时会导致某些TaskManager分配到的任务较多而其他TaskManager分配到的任务较少从而造成任务较多的TaskManager资源利用率过高成为整个作业处理的瓶颈。如图 (a) 所示给定一个包含两个顶点的 Flink 作业JobVertex-AJV-A和JobVertex-BJV-B并行度分别为6和3且两个顶点共享同一个 Slot 共享组。在默认任务调度策略下如图 (b) 所示各TaskManager上的任务分配可能出现较大差异。具体而言任务最多的TaskManager可能承载4个任务而任务最少的TaskManager可能只有2个任务。因此承载 4 个任务的TaskManager很容易成为整个作业的性能瓶颈。为此Flink 提供了基于任务数量的均衡任务调度策略能力。在作业的资源视图中它旨在使分配到每个TaskManager的任务数量尽可能接近从而改善TaskManager之间的资源利用率偏差。注意并行度不一致并不意味着必须使用该策略因为在实际场景中并不总是出现上述问题。原理基于任务数量的均衡任务调度策略通过两个阶段完成任务到TaskManager的分配第一阶段任务到 Slot 的分配第二阶段Slot 到 TaskManager 的分配本节将通过两个示例来说明该策略在这两个阶段中的简化流程与原理。第一阶段任务到 Slot 的分配以图 (c) 所示的作业为例该作业包含 5 个 JobVertex并行度分别为1、4、4、2、3且它们均属于默认 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 共享组。第一阶段分配完成后的结果如图 (g) 所示Slot0、Slot1、Slot2各包含2个任务其余 Slot 各包含1个任务。随后该策略提交所有 Slot 请求并等待当前作业所需的全部 Slot 资源就绪。一旦 Slot 资源就绪该策略按 Slot 中包含的任务数量对所有 Slot 请求进行降序排序。随后依次将每个 Slot 请求分配给当前任务负载最小的TaskManager直到所有 Slot 请求分配完毕。最终分配结果如图 (i) 所示每个TaskManager恰好承载3个任务TaskManager之间的任务数量差异为0。相比之下在默认策略下如图 (h) 所示TaskManager之间的任务数量差异为2。因此如果您遇到上述性能瓶颈问题使用该负载均衡任务调度策略可以提升性能。但如果您没有遇到上述瓶颈请不要使用该策略否则可能导致性能下降。使用方法您可以通过以下配置项启用均衡任务调度策略taskmanager.load-balance.mode:tasks注意在故障恢复场景中当资源被释放并处理资源请求时资源视图的延迟更新可能导致分配结果不够均衡。此时您可以通过适当增大 slot.request.max-interval 的值来改善这一情况。例如可以每次尝试增加50毫秒进行调整。提高该值会使 Slot 请求和可用资源视图在作业调度期间更加稳定从而使任务能够尽可能均衡地分配。但这也会相应延长任务调度阶段的整体时长从而增加 slot.request.timeout 参数超时的风险。需要强调的是如果在充分增大该选项值后仍出现非最优任务均衡的情况可在 FLINK-38715 中报告报告内容应包括调度相关配置的描述和观察到的现象。