关于flink:深入解析-Flink-细粒度资源管理

38次阅读

共计 5843 个字符,预计需要花费 15 分钟才能阅读完成。

摘要:本文整顿自阿里巴巴高级开发工程师郭旸泽 (天凌) 在 Flink Forward Asia 2021 的演讲。次要内容包含:

  1. 细粒度资源管理与实用场景
  2. Flink 资源调度框架
  3. 基于 SlotSharinGroup 的资源配置接口
  4. 动静资源切割机制
  5. 资源申请策略
  6. 总结与将来瞻望

FFA 2021 直播回放 & 演讲 PDF 下载

一、细粒度资源管理与实用场景

在 Flink1.14 之前,应用的是一种粗粒度的资源管理形式,每个算子 slot request 所须要的资源都是未知的,在 Flink 外部用一个 UNKNOWN 的非凡值来示意,这个值能够和任意资源规格的物理 slot 来匹配。从 TaskManager (以下简称 TM) 的角度来说,它领有的 slot 个数和每个 slot 的资源维度都是依据 Flink 配置动态决定的。

对于少数简略作业,现有的粗粒度资源管理曾经能够根本满足对资源效率的要求。比方上图作业,由 Kafka 读入数据后通过一些简略的解决,最终将数据写入到 Redis 中。对于这种作业,咱们很容易将上下游并发保持一致,并将作业的整个 pipeline 放到一个 SlotSharingGroup (以下简称 SSG) 中。这种状况下,slot 的资源需要是基本相同的,用户间接调整默认的 slot 配置即可达到很高的资源利用效率,同时因为不同的 task 热点峰值不肯定雷同,通过削峰填谷效应,将不同的 task 放到一个大的 slot 里,还能够进一步升高整体的资源开销。

然而对于一些生产中可能遇到的简单作业,粗粒度资源管理并不能很好地满足他们的需要。

比方图上作业,有两个 128 并发的 Kafka source 和一个 32 并发的 Redis 维表,高低两路数据处理门路。一条是两个 Kafka source,通过 join 当前再通过一些聚合操作,最终将数据 sink 到第三个 16 并发的 Kafka 中;另一条门路则是 Kafka 和 Redis 维表进行 join,后果流入一个基于 TensorFlow 的在线推断模块,最终贮存到 Reids 中。

在这个作业中粗粒度资源管理就可能导致资源利用效率升高。

首先作业上下游并发不统一,如果想把整个作业放到一个 slot 中,只能和最高的 128 并发对齐,对齐的过程对于轻量级的算子没有太大问题,然而对于比拟重的资源耗费的算子,会导致很大的资源节约。比方图上的 Redis 维表,它将所有数据都缓存到内存中来进步性能,而聚合算子则须要比拟大的 managed memory 来存储 state。对于这两个算子,原本只须要别离申请 32 和 16 份资源,对齐并发当前则别离须要申请 128 份。

同时,整个作业的 pipeline 可能因为资源过大而无奈放到一个 slot 或是 TM 中,比方上述算子的内存,再比方 Tensorflow 模块须要 GPU 来保障计算效率。因为 GPU 是一种十分低廉的资源,集群上不肯定有足够的数量,从而导致作业因为对齐并发而无奈申请到足够的资源,最终无奈执行。

咱们能够将整个作业拆分成多个 SSG。如图所示,咱们将算子依照并发划分成 4 个 SSG,保障每个 SSG 外部的并发是对齐的。然而因为每个 slot 只有一种默认规格,仍然须要将该 slot 的所有资源维度都对齐到各个 SSG 的最大值,比方内存须要和 Redis 维表的需要对齐,managed memory 须要和聚合算子对齐,甚至扩大资源中都须要退出一块 GPU,这仍然不能解决资源节约的问题。

为了解决这个问题,咱们提出了细粒度资源管理,其根本思维是,每个 slot 的资源规格都能够独自定制,用户按需申请,最大化资源的利用效率。

综上,细粒度资源管理就是通过使作业各个模块按需申请和应用资源来进步资源的整体利用效率。它的实用场景包含以下几种:作业中上下游 task 并发有显著差别、pipeline 的资源过大或者其中蕴含比拟低廉的扩大资源。这几种状况都须要将作业拆分成多个 SSG,而不同的 SSG 资源需要存在差别,这时通过细粒度资源管理就能缩小资源节约。此外,对于批工作,作业可能蕴含一个或多个 stage,不同 stage 之间资源耗费存在显著差别,同样须要细粒度资源管理来缩小资源开销。

二、Flink 资源调度框架

Flink 的资源调度框架中次要有三个角色,别离是 JobMaster (以下简称 JM),ResourceManager (以下简称 RM) 和 TaskManager。用户写好的工作首先会被编译成 JobGraph,注入资源后提交到 JM,JM 的作用就是治理 JobGraph 的资源申请以及执行部署。

JM 中的调度相干的组件是 Scheduler,它会依据 JobGraph 生成一系列 SlotRequest,而后将这些 SlotRequest 进行聚合,生成一个 ResourceRequirement 发送给 RM,RM 接到资源申明当前,首先会查看集群中现有的资源是否满足其需要,能够的话就会向 TM 发出请求,让他给对应的 JM 去 offer slot (这里 slot 的调配由 SlotManager 组件来实现)。如果现有资源不够,它会通过外部的 driver 向内部的 K8s 或者 Yarn 申请新的资源,最终 JM 接管足够多的 slot 之后就会开始部署算子,作业能力运行起来。

顺着这个框架,接下来对细粒度资源管理中的技术实现细节和 design choice 进行剖析论述。

三、基于 SlotSharingGroup 的资源配置接口

在入口处 Flink 须要将资源配置注入 JobGraph 中。这部分是 FLIP-156 中提出的基于 SlotSharingGroup 的资源配置接口,对于资源配置接口的设计抉择,次要问题是资源配置的粒度:

首先是最小的算子粒度 operator。如果用户在 operator 上配置资源的话,Filnk 须要依据 chaining 和 slot sharing 进一步将资源聚合成 slot 级别再进行资源调度。

应用这个粒度的益处是,咱们能够将资源配置与 chaining 和 slot sharing 的逻辑解耦,用户只须要思考以后算子的需要,而无须思考它是否和其余算子嵌在一起或者是否调度到一个 slot 中。其次,它使 Flink 能够更精确地计算每个 slot 的资源。如果某一个 SSG 中上下游算子领有不同的并发,那么可能 SSG 对应的物理 slot 须要的资源也是有差别的;而如果 Flink 把握了每个算子的资源,它就有机会进一步优化资源效率。

当然它也存在一些毛病,首先是用户配置老本过高,生产中的简单作业蕴含了大量算子,用户很难一一配置。其次,这种状况下,很难反对粗细粒度混合资源配置。一个 SSG 中如果既存在粗粒度,又存在细粒度的算子,会导致 Flink 无奈判断其所须要的资源到底是多少。最初,因为用户对资源的配置或预计会存在肯定水平的偏差,这种偏差会一直累积,算子的削峰填谷效应也无奈被无效利用。

第二种抉择是将算子 chaining 后造成的 task 作为资源配置的粒度。这种状况下,咱们必须向用户裸露 Flink 外部的 chaining 逻辑,同时 Flink 的 runtime 仍然须要依据 task 的 slot sharing 的配置进一步将资源聚合成 slot 级别再进行资源调度。

它的优缺点和算子粒度大抵一样,只不过相比算子,它在用户的配置老本上有了肯定水平的升高,但这仍然是一个痛点。同时它的代价是无奈将资源配置和 chaining 解耦,将 chaining 和 Flink 外部的逻辑裸露给用户,导致外部潜在的优化受到限制。因为一旦用户配置了某个 task 的资源,chaining 逻辑的扭转可能让 task 决裂成两个或者三个,造成用户配置不兼容。

第三种抉择是间接将 SlotSharingGroup 作为资源配置的粒度,这样对 Flink 来说资源配置所见既所得,省略了后面的资源聚合逻辑。

同时这种抉择还有以下几个长处:

  • 第一,使用户的配置更灵便。咱们将配置粒度的选择权交给用户,既能够配置算子的资源,也能够配置 task 资源,甚至配置子图的资源,只须要将子图放到一个 SSG 里而后配置它的资源即可。
  • 第二,能够较为简单地反对粗细粒度混合配置。所有配置的粒度都是 slot,不必放心同一个 slot 中既蕴含粗粒度又蕴含细粒度的 task。对于粗粒度的 slot,能够简略地依照 TM 默认的规格计算它的资源大小,这个个性也使得细粒度资源管理的调配逻辑能够兼容粗粒度调度的,咱们能够把粗粒度看作是细粒度的一种特例。
  • 第三,它使得用户能够利用不同算子之间的削峰填谷效应,无效缩小偏差产生的影响。

当然,也会引入一些限度,它将资源配置的 chaining 以及 Slot Sharing 耦合在了一起。此外如果一个 SSG 里算子存在并发差别,那么为了最大化资源利用效率,可能须要用户手动拆组。

综合思考,咱们在 FLIP-156 中,最终抉择了基于 SlotSharingGroup 的资源配置接口。除了上述提到的长处,最重要的是从资源调度框架中能够发现,slot 实际上就是资源调度中最根本的单位,从 Scheduler 到 RM\TM 都是以 slot 为单位进行资源调度申请的,间接应用这个粒度,防止了减少零碎的复杂度。

回到示例作业,在反对了细粒度资源管理配置接口后,咱们就能够为 4 个 SSG 配置不同的资源,如上图所示。只有调度框架严格依照这个准则进行匹配,咱们就能够最大化资源利用效率。

四、动静资源切割机制

解决了资源配置当前,下一步就是为这些资源申请 slot,这一步须要用到 FLIP-56 提出的动静资源切割机制。

简略回顾一下这幅图,当初最左侧的 JobGraph 曾经有资源了,往右走就进入了 JM、RM 和 TM 的资源调度。在粗粒度资源管理下,TM 的 slot 都是固定大小、依据启动配置来决定的,RM 在这种状况没法满足不同规格的 slot 申请的,因而咱们须要对 slot 的创立形式进行肯定的革新。

先来看现有的动态 slot 申请机制。实际上 TM 启动的时候 slot 就曾经划分好了,并且标记了编号。它会将这些 slot 上报给 Slot Manager,slot request 来长期 Slot Manager 会决定申请 slot1、slot3,最初 slot1 上的 task 运行完当前会开释 slot。这种状况下,只有 slot3 处于占用的状态。咱们能够发现,这时尽管 TM 有 0.75 core,3G 的闲暇资源,但如果 job 去申请对应资源大小的 slot,TM 也无奈满足它,因为 slot 曾经提前划分好了。

因而咱们提出了动静资源切割机制。slot 不再是 TM 启动后就生成并且不变的,而是依据理论 slot 的申请动静地从 TM 上切割下来。TM 启动时,咱们把能调配给 slot 的资源看作是一整个资源池,比方上图有 1core,4G 内存的资源,当初有一个细粒度的作业,Slot Manager 决定从 TM 上要一个 0.25core,1G 的 slot,TM 会查看本人的资源池是否可能切下这个 slot,而后动静生成 slot 并调配对应的资源给 JM,接下来这个作业又申请一个 0.5core,2G 的 slot,Slot Manager 还是能够从同一个 TM 上申请 slot,只有不超过闲暇资源就能够。当某个 slot 不再须要时,咱们能够将它销毁,对应的资源会回到闲暇资源池。

通过这种机制,咱们解决了细粒度资源申请如何满足的问题。

回到示例作业,咱们只须要起 8 个同样规格的 TM 就能调度作业,每个 TM 上带一块 GPU 来满足 SSG4,之后将 CPU 密集型的 SSG1 和内存密集型的 SSG2 和 SSG3 进行混布,对齐 TM 上整体的 CPU 内存比即可。

五、资源申请策略

何谓资源申请策略?它蕴含 RM 与 Resource Provider 还有 TM 交互时的两个决策,一个是从 Resource Provider 处申请什么资源规格的 TM 以及各个规格 TM 各须要几个,另一个是如何将 slot 摆放到各个 TM 中。实际上这两个决策都是在 Slot Manager 组件外部进行的。

粗粒度的资源申请策略比较简单,因为只存在一种规格的 TM,并且 slot 规格都是一样的。在调配策略上只须要思考是否将 slot 尽量平铺到各个 TM。但在细粒度资源管理下的策略就须要思考到不同的需要。

首先咱们引入了动静资源切割机制。slot 的调度就能够看作一个多维装箱问题,既须要思考如何缩小资源碎片,也须要保障资源调度效率。此外还有 slot 是否须要评估,以及集群可能对 TM 的资源规格有一些要求,比方不能过小,在 K8s 上如果 TM 资源过小,会导致启动过慢,最初注册超时,但也不能太大,会影响 K8s 的调度效率。

面对上述复杂性,咱们将这个资源申请策略形象进去,定义了一个 ResourceAllocationStrategy,Slot Manager 会将以后的资源申请和集群中现有的可用资源通知 strategy,strategy 负责决策并通知 Slot Manager 现有资源如何调配、还须要申请多少个新的 TM 以及它们别离的规格,还有是否存在无奈满足的作业。

目前细粒度资源管理还处于 beta 版本,社区内置了一个简略的默认资源管理策略。在这个策略下 TM 的规格是固定的、依据粗粒度的配置决定的,如果某个 slot 的申请大于资源配置,可能导致无奈调配,这是它的局限性。在资源分配方面,它会程序扫描以后闲暇的 TM,只有满足 slot 的申请就会间接切割,这种策略保障了资源调度即便在大规模的工作上也不会成为瓶颈,但代价是无奈防止资源碎片的产生。

六、总结与将来瞻望

细粒度资源管理目前在 Flink 中还只是 beta 版本。上图能够看到,对于 runtime 来说,通过 FLIP-56 与 FLIP-156,细粒度资源管理的工作曾经根本实现了。而从用户接口的角度,FLIP-169 曾经凋谢了 Datastream API 上的细粒度配置,具体如何配置,能够参考社区的用户文档。

将来,咱们的倒退方向次要是以下几个方面:

  • 第一,定制更多的资源管理策略来满足不同场景,比方 session 和 OLAP 等;
  • 第二,目前咱们是把扩大资源看作一个 TM 级别的资源,TM 上的每个 slot 都能够看到它的信息,之后咱们会对它的 scope 进行进一步限度;
  • 第三,目前细粒度资源管理能够反对粗细粒度混合配置,然而存在一些资源效率上的问题,比方粗粒度的 slot 申请能够被任意大小的 slot 满足,将来咱们会进一步优化匹配逻辑,更好地反对混合配置;
  • 第四,咱们会思考适配社区新提出的 Reactive Mode;
  • 最初,对 WebUI 进行优化,可能展现 slot 的切分信息等。

FFA 2021 直播回放 & 演讲 PDF 下载

更多 Flink 相干技术问题,可扫码退出社区钉钉交换群
第一工夫获取最新技术文章和社区动静,请关注公众号~

正文完
 0