flink的架构

(1)flink的任务提交流程(无Dispatcher提交)

  1、client向yarn提交application后,同时向HDFS上传flink的Jar包和配置。ResourceManager为application分配Container资源并通知对应的NodeManager启动ApplicationMaster。

  2、ApplicationMaster启动后加载Flink的Jar包和配置,构建环境以启动JobManager。JobManager首先接收应用程序的相关资源如jobgraph,会将JobGraph转换成物理层面的数据流图ExecutionGragh。

  4、JobManager向ResourceManager申请Container启动TaskManager,ResourceManager分配Container资源后,通知资源所在节点的NodeManager启动TaskManager。每个TaskManager都包含一定数量的插槽slots,插槽的数量限制了TaskManager能够执行的任务数量。

  6、TaskManager会向ResoureManger注册它的插槽,收到ResourceManger的指令后,TaskManager就会将若干个插槽提供个JobManager调用,JobManager就可以向插槽分配任务(tasks)来执行。

  注意:一个nodemanager可以有多个TaskManager的,每个container都会有一个TaskManager。

(2)flink中各个组件的作用

  1、JobManager:Flink系统的协调者,它负责接收Flink Job,并负责调度Task的执行。同时JobManager还负责收集Job的状态信息,并管理Flink集群中的从节点TaskManager。

  2、TaskManager:从 Job Manager 处接收需要部署的 Task。负责管理其所在节点上的资源信息,如内存、磁盘、网络,在启动的时候将资源的状态向JobManager汇报。

  3、client:Client 不是 Flink 程序执行的内部部分,但它是任务执行的起点。Client 负责接受用户的程序代码,然后创建数据流,将数据流提交给JobManager以便进一步执行。执行完成后,Job Client 将结果返回给用户。

  4、Slot :理解为是资源的最小管理单位,它是TaskManager资源的一个子集。通过slot,flink将资源进行有效的划分和管理。flink中允许一个任务的不同子任务共享同一个slot,也允许不同任务的不同子任务共享同一个slot,前提是这些子任务不属于同一种操作类型的任务。通过slot共享,能够让资源密集型子任务(Source,Map)和资源密集型子任务(KeyBy/Window/Apply)能够充分利用资源,避免闲的闲死,忙的忙死。

  5、TaskManager与slots的关系:

   1)每个TaskManager是一个JVM进程,它可能会在独立的线程上执行一个或多个subtask。为了控制一个TaskManager能接收多少个task,TaskManager通过task slot来进行控制(一个TaskManager至少有一个task slot)。

   2)每个task slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分成三份给各个slot。资源slot化意味着一个subtask将不需要跟来自其他job的subtask竞争被管理的内存,取而代之的是它将拥有一定数量的内存储备。需要注意的是,这里不会涉及到CPU的隔离,slot目前仅仅用来隔离task的受管理的内存。

   3)通过调整task slot的数量,允许用户定义subtask之间如何互相隔离。如果一个TaskManager一个slot,那将意味着每个task group运行在独立的JVM中(该JVM可能是通过一个特定的容器启动的),而一个TaskManager多个slot意味着更多的subtask可以共享同一个JVM。

(3)flink的任务调度原理:Flink中的执行资源通过任务槽(Task Slots)来定义。每个TaskManager都有一个或多个任务槽,每个槽都可以运行一个并行任务管道(pipeline of parallel tasks)。管道由多个连续任务组成,例如MapFunction的第n个并行实例以及ReduceFunction的第n个并行实例。

  1、考虑一个带有数据源,MapFunction和ReduceFunction的程序。源和MapFunction以4的并行度(parallelism)执行,而ReduceFunction以3的并行度执行。管道由序列Source - Map - Reduce组成。在具有2个TaskManagers且每个具有3个插槽的群集上,程序将按如下所述执行。

(4)flink的执行图

  1、StreamGraph:根据用户通过 Stream API 编写的代码生成的最初的图。用来表示程序的拓扑结构。

  2、JobGraph:StreamGraph经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。主要的优化为,将多个符合条件的节点 chain 在一起作为一个节点,这样可以减少数据在节点之间流动所需要的序列化/反序列化/传输消耗。

  3、ExecutionGraph:JobManager 根据 JobGraph 生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本,是调度层最核心的数据结构。

  4、物理执行图:JobManager 根据 ExecutionGraph 对 Job 进行调度后,在各个TaskManager 上部署 Task 后形成的“图”,并不是一个具体的数据结构。

(5)并行数据流:

  Flink程序的执行具有并行、分布式的特性。在执行过程中,一个 stream 包含一个或多个 stream partition ,而每一个 operator 包含一个或多个 operator subtask,这些operator subtasks执行过程中,彼此相互独立。

  一个特定operator的subtask的个数被称之为operator的parallelism(并行度)。一个stream的并行度总是等同于其producing operator的并行度。一个程序中,不同的operator可能具有不同的并行度。

  Streamoperator之间传输数据的形式可以是one-to-one(forwarding)的模式也可以是redistributing的模式,具体是哪一种形式,取决于operator的种类。

  1、one-to-one:类似于spark中的窄依赖,map、fliter、flatMap等算子都是one-to-one的对应关系。

  2、Redistributing:类似于spark中的宽依赖,stream(map()跟keyBy/window之间或者keyBy/window跟sink之间)的分区会发生改变。每一个operator subtask依据所选择的transformation发送数据到不同的目标subtask。keyBy()和rebalance会随机重新分区,这些算子都会引起redistribute。

(6)task与operate chains

  相同并行度的one to one操作,Flink这样相连的operator 链接在一起形成一个task,原来的operator成为里面的subtask。将operators链接成task是非常有效的优化:它能减少线程之间的切换和基于缓存区的数据交换,在减少时延的同时提升吞吐量。链接的行为可以在编程API中进行指定。

  1、operatorChain的优点:减少线程切换,减少序列化与反序列化,减少延迟并且提高吞吐量

  2、operatorChain组成条件:上下游算子并行度一致,上下游算子之间没有shuffle

 

posted on 2020-05-27 17:48  hdc520  阅读(507)  评论(0编辑  收藏  举报

导航