一、flink运行时组件:

 

 1、JobManager(作业管理器)

  • 控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的JobManager所控制执行。
  • JobManager会先接收到要执行的应用程序,这个应用程序包括:作业图(JobGraph)、逻辑数据流图(logical dataflow graph)、打包了所有的类、库和其他资源的jar包。
  • JobManager会把JobGraph转换成一个屋里层面的数据流图,这个图被叫做执行图(ExecutionGraph),包含了所有可以并发执行的任务。
  • JobManager会向资源管理器(ResourceManager)请求执行任务必要的资源,也就是任务管理器(TaskManager)上的插槽(slot)。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的TaskManager上,而在运行过程中,JobManager会负责所有需要中央协调的操作,比如检查点(checkpoints)的协调。

2、TaskManager(任务管理器)

  • 是Flink中的工作进程。通常在Flink中会有多个TaskManager运行,每一个TaskManager都包含了一定数量的插槽(slots)。插槽的数量限制了TaskManager能够执行的任务数量。
  • 启动之后,TaskManager会向资源管理器注册它的插槽;收到资源管理器的指令后,TaskManager就会将一个或多个插槽提供给JobManager调用,JobManager就可以向插槽分配任务(tasks)来执行了。
  • 在执行的过程中,一个TaskManager可以跟其它运行同一应用程序的TaskManager交换数据。

3、ResourceManager(资源管理器)

  • 主要负责任务管理器的插槽,TaskManager插槽是flink中定义的处理资源单元。
  • flink为不同的环境和资源管理工具提供了不同的资源管理器,比如yarn、mesos、k8s,以及standalone部署。
  • 当JobManager申请插槽资源时,ResourceManager会将有空闲插槽的TaskManager分配给JobManager,如果ResourceManager没有足够的插槽来满足JobManager的请求,它还可以向资源提供平台发起会话,以提供启动TaskManager进程的容器。

4、Dispatcher(分发器)

  • 可以跨作业运行,它为应用提交提供了REST接口。
  • 当一个应用被提交执行时,分发器就会启动并将应用移交给一个JobManager。
  • Dispatcher也会启动一个webui,用来方便地展示和监控作业执行的信息。
  • Dispatcher在架构中可能并不是必须的,这取决于应用提交运行的方式。

Flink客户端:

用来提交Flink作业到Flink集群中,在客户端中负责Stream Graph(流图)和Job Graph(逻辑作业图)的构建(使用Table Api和SQL编写的Flink应用还会在客户端中负责SQL解析和优化)。

Dispatcher:

Dispatcher可以接收多个作业,每接收一个作业,Dispatcher都会为这个作业分配一个JobManager。
Dispatcher对外提供一个表述性状态转移(REST)式的接口,以超文本传输协议来对外提供服务

JobManager:

一个Flink作业的协调者,一个作业会有一个JobManager来负责。
JobManager将Client提交的JobGraph转化为ExecutionGraph(物理执行图)
向ResourceManager申请必要的资源,当获取到足够的资源后
JobManager将ExecutionGraph以及具体的计算任务分发部署到多个TaskManager上
同时JobManager还负责管理多个TaskManager,包括收集作业的状态信息、生成检查点、必要时进行故障恢复等。

TaskManager:

是实际负责执行的计算节点。
单个TaskManager提供一定量的slot,TaskManager启动后相关的slot信息会被注册到ResourceManager中。
当某个作业提交后,ResourceManager会将空闲的slot提供给JobManager,获取到空闲的slot后会将具体的计算任务部署到空闲slot上开始执行,执行过程中,由于进行数据交换,TaskManager之间进行必要的数据通信。

ResourceManager:

Flink使用一个名为ResourceManager的模块来统一处理资源分配上的问题。
flink中计算资源基本单位是TaskManager上的任务槽slot,ResourceManager的职责主要是从Yarn等资源提供方获取计算资源,当JobManager有计算需求时,将空闲的slot分配给JobManager,当计算结束时,ResourceManager还会重新收回这些slot。

二、任务提交流程

 

 

上图是从一个较为高层级的视角,来看应用中各组件的交互协作。如果部署的集群环境不同(例如YARN,Mesos,Kubernetes,standalone等),其中一些步骤可以被省略,或是有些组件会运行在同一个JVM进程中。

具体地,如果我们将Flink集群部署到YARN上,那么就会有如下的提交流程:

 

 

  Flink任务提交后,Client向HDFS上传Flink的Jar包和配置,之后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster,ApplicationMaster启动后加载Flink的Jar包和配置构建环境,然后启动JobManager,之后ApplicationMaster向ResourceManager申请资源启动TaskManager,ResourceManager分配Container资源后,由ApplicationMaster通知资源所在节点的NodeManager启动TaskManager,NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager,TaskManager启动后向JobManager发送心跳包,并等待JobManager向其分配任务。

 

  • 并行的任务,需要占用多少个slots?
    •   需要先分组,每个组里面最大的task数即为需要slot的数量。
  • 一个流处理程序,到底包含多少个任务?

Flink中每个算子后面都可以设置并行度,一般情况下,一个stream的并行度,可以认为就是其所有算子中最大的并行度。

 

 如上图所示,看起来应该是有7个task,实际上某些task可以合并如下。

 

 那么在运行的时候真的需要占用这么多的slot吗?或者必须要有5个slot这个job才能执行起来吗?

 

默认情况下,Flink允许子任务共享slot,即使他们时不同任务的子任务,这样的结果是一个slot可以保存作业的整个管道。

但是相同操作的不同task任务,是不能共享slot的,不能在一个slot上执行。

 

 如果不想一个slot共享,需要算子后面设置不同的共享组。setSharingGroup(""),默认是使用共享组并且共享组名为default。

 

   Flink中依据什么来划分task是否能合并?

    必须是共享组、并行度相同、并且是one-to-one的操作

    如果不想合并,代码层面设置disableOperatorChaining或startnewchain

 

 

执行图:
Flink中的执行图可以分为四层:StreamGraph -> JobGraph -> ExecutionGraph ->物理执行图

StreamGraph:是根据用户通过Stream API编写的代码生成的最初的图,用来表示程序的拓扑结构。
JobGraph:StreamGraph经过优化后生成了JobGraph,提交给Jobmanager的数据结构。主要的优化为,将多个符合条件的节点chain在一起作为一个节点。
ExecutionGraph:Jobmanager根据JobGraph生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本,是调度层最核心的数据结构。
物理执行图:JobManager根据ExecutionGraph对Job进行调度后,在各个TaskManager上部署Task后形成的图,并不是一个具体的数据结构。

 

 

 数据的传输形式:

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

one-to-one:stream维护这分区以及元素的顺序,这意味着map算子的子任务看到的元素的个数以及顺序跟source算子的子任务生产的元素的个数、顺序相同。map、filter、flatmap等算子都是one-to-one的对应关系。(类似于spark中的窄依赖)

redistributing:stream的分区会发生改变,每一个算子的子任务依据所选择的transformation发送数据到不容的目标任务。例如keyby基于hashcode重分区、而broadcast和rebalance(轮询,而shuffle是完全随机的)会随机重新分区,这些算子都会引起redistribute过程,而redistribute过程就类似于spark中的shuffle过程。(类似于spark中的宽依赖)

 

posted on 2020-12-16 23:44  -星星点灯丶  阅读(111)  评论(0编辑  收藏  举报