本页介绍细粒度资源管理的用法、适用场景及其工作原理。
注意:此功能目前是 MVP(“最小可行产品”)功能,仅适用于 DataStream API。
可能受益于细粒度资源管理的典型方案包括:
在如何提高资源效率中,深入探讨了细粒度资源管理如何提高上述场景的资源效率。
如 Flink 架构中所述,任务管理器中的任务执行资源被拆分为多个槽。该槽是 Flink 运行时中资源调度和资源需求的基本单位。
通过细粒度资源管理,槽请求包含用户可以指定的特定资源配置文件。Flink 将尊重用户指定的资源要求,并从 TaskManager 的可用资源中动态剪切一个完全匹配的插槽。如上所示,需要一个具有 0.25 Core 和 1GB 内存的插槽,而 Flink 会为其分配插槽 1。
以前在 Flink 中,资源需求仅包含所需的插槽,没有细粒度的资源配置文件,即粗粒度资源管理。TaskManager具有固定数量的相同插槽来满足这些要求。
对于没有指定资源配置文件的资源要求,Flink 将自动决定资源配置文件。目前,它的资源配置文件是根据 TaskManager 的总资源和 taskmanager.numberOfTaskSlots 计算得出的,就像在粗粒度资源管理中一样。如上所示,TaskManager 的总资源为 1 个核心和 4 GB 内存,任务槽数设置为 2,插槽 2 创建时具有 0.5 核心和 2 GB 内存,以满足没有指定资源配置文件的要求。
分配插槽 1 和插槽 2 后,任务管理器中将剩下 0.25 个核心内存和 1 GB 内存作为可用资源。可以对这些可用资源进行进一步分区,以满足以下资源要求。
有关更多详细信息,请参阅资源分配策略。
要使用细粒度资源管理,您需要:
若要启用细粒度资源管理,需要将群集配置为“细粒度资源管理”。启用 true。
如果没有此配置,Flink 运行时将无法根据您指定的资源要求调度插槽,并且作业将失败并出现异常。
细粒度资源要求在插槽共享组上定义。插槽共享组是一个提示,告诉其中的JobManager 算子/任务可以放入同一插槽中。
要指定资源要求,您需要:
有两种方法可以定义插槽共享组及其包含的算子:
您可以为插槽共享组指定资源配置文件:
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
SlotSharingGroup ssgA = SlotSharingGroup.newBuilder("a")
.setCpuCores(1.0)
.setTaskHeapMemoryMB(100)
.build();
SlotSharingGroup ssgB = SlotSharingGroup.newBuilder("b")
.setCpuCores(0.5)
.setTaskHeapMemoryMB(100)
.build();
someStream.filter(...).slotSharingGroup("a") // Set the slot sharing group with name “a”
.map(...).slotSharingGroup(ssgB); // Directly set the slot sharing group with name and resource.
env.registerSlotSharingGroup(ssgA); // Then register the resource of group “a”
注意:每个插槽共享组只能附加到一个指定的资源,任何冲突都将使您的作业编译失败。
在构造插槽共享组时,可以为插槽共享组设置以下资源组件:
SlotSharingGroup ssgWithResource =
SlotSharingGroup.newBuilder("ssg")
.setCpuCores(1.0) // required
.setTaskHeapMemoryMB(100) // required
.setTaskOffHeapMemoryMB(50)
.setManagedMemory(MemorySize.ofMebiBytes(200))
.setExternalResource("gpu", 1.0)
.build();
// Build a slot sharing group without specific resource and then register the resource of it in StreamExecutionEnvironment
SlotSharingGroup ssgWithName = SlotSharingGroup.newBuilder("ssg").build();
env.registerSlotSharingGroup(ssgWithResource);
注: 您可以构造一个 SlotSharingGroup,同时指定或不指定其资源配置文件。通过指定资源配置文件,您需要显式设置具有正值的 CPU 内核和任务堆内存,其他组件是可选的。
由于细粒度资源管理是一项新的实验性功能,因此并非所有默认计划程序支持的功能都随之可用。Flink 社区正在努力解决这些限制。
在本节中,我们将深入探讨细粒度资源管理如何提高资源效率,这可以帮助您了解它是否能使您的工作受益。
以前,Flink 采用粗粒度资源管理方法,将任务部署到预定义的、通常相同的插槽中,而无需了解每个插槽包含多少资源。对于许多作业,使用粗粒度资源管理并简单地将所有任务放入一个插槽共享组中,在资源利用率方面已经足够好了。
但是,在某些情况下,粗粒度资源管理效果不佳。
尝试执行具有相同槽位的所有任务可能会导致资源利用率不理想。相同插槽的资源必须能够满足最高的资源要求,这将浪费其他要求。当涉及昂贵的外部资源(如GPU)时,这种浪费可能会变得更加难以承受。细粒度资源管理利用不同资源的槽位来提高此类场景下的资源利用率。
在本节中,我们将讨论 Flink 运行时中的槽分区机制和资源分配策略,包括 Flink 运行时如何选择 TaskManager 来剪切槽,并在 Native Kubernetes 和 YARN 上分配 TaskManagers。请注意,资源分配策略在 Flink 运行时中是可插入的,在这里,我们将在细粒度资源管理的第一步中介绍其默认实现。将来,用户可能会为不同的方案选择各种策略。
如“工作原理”部分所述,Flink 将从 TaskManager 中为具有指定资源的插槽请求切出一个完全匹配的插槽。内部流程如上所示。任务管理器将使用总资源启动,但没有预定义的插槽。当具有 0.25 Core 和 1GB 内存的插槽请求到达时,Flink 将选择具有足够可用资源的 TaskManager,并使用请求的资源创建一个新插槽。如果释放了某个插槽,它将其资源返回到 TaskManager 的可用资源。
在当前的资源分配策略中,Flink 将遍历所有已注册的任务管理器,并选择第一个具有足够可用资源来满足槽位请求的 TaskManager。当没有足够可用资源的 TaskManager 时,Flink 会在 Native Kubernetes 或 YARN 上部署时尝试分配一个新的 TaskManager。在当前策略中,Flink 会根据用户的配置分配相同的任务管理器。由于 TaskManagers 的资源规范是预定义的: