第三章 Flink运行架构

前言

大家好, 我是上白书妖!

知识源于积累,登峰造极源于自律

今天我根据以前所以学的一些文献,笔记等资料整理出一些小知识点,有不当之处,欢迎各位斧正

 

Flink运行时的组件

Flink运行时架构主要包括四个不同的组件,它们会在运行流处理应用程序时协同工作:
        作业管理器(JobManager)、资源管理器(ResourceManager)、任务管理器(TaskManager),以及分发器(Dispatcher)。
因为Flink是用Java和Scala实现的,所以所有组件都会运行在Java虚拟机上。 每个组件的职责如下:

① 作业管理器(JobManager)

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

 
 
上白书妖补充对作业管理器(JobManager)的理解:

         JobManager是控制整个Flink
Job运行的,所谓的控制就是,①他负责监控②他负责Slot的分配或者Slot的调度.这个Task在哪个Slot上运行,他给你分配好,这就是所谓的控制,JobManager就一句话,就是用来控制Flink
Job的主进程的运行.
         什么叫控制?
         控制的意思就是说你整个Job分成好几个任务,那么我这几个任务我需要把他分配到哪些Task
Manager的哪些Slot上,这个Slot就表示资源的意思,同时还负责监控.

 
上白书妖博客

 
 
 

②资源管理器(ResourceManager)

         主要负责管理任务管理器(TaskManager)的插槽(slot),TaskManger插槽是Flink中定义的处理资源单元。Flink为不同的环境和资源管理工具提供了不同资源管理器,比如YARN、Mesos、K8s,以及standalone部署。当JobManager申请插槽资源时,ResourceManager会将有空闲插槽的TaskManager分配给JobManager。如果ResourceManager没有足够的插槽来满足JobManager的请求,它还可以向资源提供平台发起会话,以提供启动TaskManager进程的容器。另外,ResourceManager还负责终止空闲的TaskManager,释放计算资源。

 
 
上白书妖补充对资源管理器(ResourceManager)的理解:

       JobManager会向资源管理器(ResourceManager)请求执行任务必要的资源,也就是任务管理器(TaskManager)上的插槽(slot)

      ResourceManager如果是yarn模式的话,这个在hadoop就讲过了.但是如果是Standalone模式的话.这个ResourceManager实际上就和我们的JobManager在一个进程里面,这点需要注意.但是如果是yarn模式的话,ResourceManager是独立的,是yarn里面的主节点,主要负责资源的管理,管理所有Task
Manager上的Slot.
      这里面有个迷糊的地方,这个ResourceManager早就在hadoop上学过了,但是为什么说他是管理所有Task
Manager的Slot呢?问题是,你这个Task
Manager是属于你的Flink的.原来我们学Hadoop的时候说的是,ResourceManager是管理NodeManager上的资源的.可是,现在我们又说是管理Task
Manager上的资源.这两句话难道是一样的吗?其实,这两句话本质上是一样的.为什么呢?因为,请问,在yarn模式下,这个TaskManager这个节点会运行在哪些节点上呢?是运行在NodeManager节点上呢?还是在ResourceManager节点上?还是运行在与NodeManager和ResourceManager都没关系的其他节点上呢?其实,他一定是运行在NodeManager上,并且他只能运行在NodeManager上,他是在NodeManager上去启动TaskManager.那如果是这样的话.你在NodeManager上启动TaskManager的话,你不就是申请NodeManager上的资源嘛.申请了NodeManager上的资源你才能够启动对应的TaskManager.所以说,我们之前学的ResourceManager就是来管理和分配NodeManager上的资源的.这句话是对的.由于你NodeManager上有资源,所以他可以在某一个NodoManager上去启动Flink
Job需要运行的TaskManager.假设在hadoop102上的NodeManager上启动了一个TaskManager,他之所以能够启动,一定是他有空余的资源才能够启动.假设他有空余一个G的资源,那启动了一个TaskManager.(为什么这里说是一个G呢?因为我们配置文件中指定了默认情况下TaskManager占用内存是一个G,所以这和Flink的配置文件是关联起来的).所以,假设是启动一个G,这一个G是给TaskManager用的,并且你指定了TaskManager上的Slot数量是3,那么他会把这一个G的资源均匀的切成三份,分给这三个Slot.由于在我们Flink这个框架里面,我们的资源是在TaskManager上的Slot的,所以我们也可以用另外一句话来描述,就是说,我们ResourceManager来负责管理和分配TaskManager上的Slot.

上白书妖博客
上白书妖博客
 
 

③任务管理器(TaskManager)

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

 

上白书妖补充对任务管理器(TaskManager)的理解:

       TaskManager是在Flink
job运行过程中,是他的工作进程.TaskManager一定是一个进程.每一个TaskManager包含一定数量的Slot.这个Slot的数量就限制了你这个TaskManager的并行执行任务的数量.
      那Slot的数量是在哪里设置的呢?
就是在你的配置文件中设置的.也可以在命令中设置.这个命令是yarn-session -s…略…(这个-s 里面就是你的Slot数量)
      上面详细说过,这Slot是共享整个TaskManager上的内存资源的.如果你这个TaskManager是一个G,那么我三个Slot都共享这一个G.
还有一点就是,在yarn模式下,这个TaskManager是在你的Flink Job
提交之后,根据你这个Job的资源的需求情况来启动这个TaskManager的.当前,前提条件是基于你的yarn模式,不是基于standalone模式的.
所以,这个TaskManager在yarn模式中是这样的.就是你这Job一提交,ResourceManager根据你提交的Job运行时候的执行图,确定你需要多少Slot.假设你需要三个Slot,ResourceManager发现你需要三个Slot,那ResourceManager就只需要启动一个TaskManager就可以了.因为一个TaskManager上就有三个Slot(配置文件上指定的),够用了.尽管其他的NodeManager上也可以启动TaskManager,但是这就没必要启动了.这就是Flink的特点.Flink和MapReduce和Spark不一样.他不是在Job没提交之前就将所有改启动的都先启动了.因为这样有些东西的浪费的.比如Work进程里面的executor,他尽管没有运行executor,他也运行在哪里,这就很浪费.
       所以,当假设你需要三个Slot,那我就给你启动一个TaskManager,这时候你肯定还有其他空闲的资源,这时候,我用户还可以提交一个新的Flink
Job进来.新的Flink job也是一样,ResourceManager根据你这个新的Flink
job运行的资源,需求情况,又给你去启动对应的TaskManager.
      新问题: 假设我写的task任务(即task
job)运行的时候需要的Slot比较多.我需要九个Slot.如果你资源有的情况下,他一定会给你启动三个TaskManager.反正他启动的TaskManager一定是够你这个task
Job用的.除非我ResourceManager所管理的资源已经没有了,那就没办法了,只能等待.因为他已经没有资源给你运行了

 
 

④分发器(Dispatcher)

       分发器(Dispatcher):可以跨作业运行,它为应用提交提供了REST接口。当一个应用被提交执行时,分发器就会启动并将应用移交给一个JobManager。由于是REST接口,所以Dispatcher可以作为集群的一个HTTP接入点,这样就能够不受防火墙阻挡。Dispatcher也会启动一个Web
UI,用来方便地展示和监控作业执行的信息。Dispatcher在架构中可能并不是必需的,这取决于应用提交运行的方式。

 
 
上白书妖补充对分发器(Dispatcher)的理解:

     什么是分发器呢?如果我通过谷歌访问Flink的web-UI界面,访问的端口号是默认的是8081,这个就是Dispatcher(分发器).
     在Flink自带的standalone模式下也是有Dispatcher(分发器)的.在Yarn模式下也是有的.那个Dispatcher是在哪里呢?分发器其实他是在JobManager里面的.
     实际上,在实际操作中我们先打开了8088这个hadoop的yarn的页面,在8088这个页面看到了Application,Application这一行的最右面有一个ApplicationMaster的超链接,点击这个ApplicationMaster就打开了我们的Dispatcher(分发器)了.
     所以Dispatcher实际上就是给我们提供的一个restful的一个接口.restful接口实际上就是可以通过HTTP来接入的.
     要知道,在standalone和yarn模式下都有Dispatcher的.

  
 
 

任务提交流程

       这个提交流程就是我写好的一个Flink的job或者写好的一个Flink的程序program.现在我要提交到Flink集群中去运行了.提交有两种提交方式:
       第一种是通过Web-UI进行提交,这个很秀,因为spark就没有这个功能,Web-UI中首先上传了一个jar包,然后在jar包中指定我要运行那个主类,传什么样的参数,等等,然后点击提交(Submit).一点击提交,就会把我们的Application或者说我们的Flink
Job提交给JobManager了.JobManager马上去ResourceManager中申请资源即去ResourceManager中申请Slot.假设我只需要三个Slot就ok了,这个时候他就找到一个对应的TaskManager,因为我们一个TaskManager默认情况下我们设置的是三个Slot.(当然这三个是我们设置的,原始的配置文件默认只有一个;当然在真正生产环境下不可能一个TaskManager只有一个Slot的,至少是三的几倍).启动相应的TaskManager,然后开始注册我们的Slot,注册Slot就表示我这个Slot开始要运行了,然后发出提供Slot的指令,然后开始提供Slot来运行.真正我们的Task是在Slot中运行的,运行的时候他还会把运行的状态信息提供给TaskManager和JobManager.如果有多个TaskManager,在TaskManager之间他是可以交换数据的.为什么可以交换数据呢?为什么TaskManager之间可以交换数据呢?如果有多个TaskManager的话,TaskManager之间是可以交换数据的.不单单是多个TaskManager,你如果是一个TaskManager和多个Slot之间也是可以交换数据的.为什么呢?
        因为假设其中一个Slot运行一个Source ,source运行完成之后把数据要给谁呢?是要把数据给转换算子,这个转换算子有可能在另外一个Slot中.那么数据是不是就得给他呢.
那么,有没有一种可能就是,你的转换算子的任务是运行在另外一个TaskManager上的Slot中,那我是不是需要把数据给他呢.
当然,这就属于跨机器了.所以要交换数据. 当然,这些都是属于站在上帝的视角看的.

 
 

我们来看看当一个应用提交执行时,Flink的各个组件是如何交互协作的:
任务提交和组件交互流程

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

 
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向其分配任务。

 
 
上白书妖解释补充图 Yarn模式任务提交流程:
图 Yarn模式任务提交流程
图 Yarn模式任务提交流程
 
 
  
 
 
 
 

任务调度原理

任务调度原理
 
 
上白书妖解释补充任务调度原理:

上白书妖解释补充任务调度原理

客户端不是运行时和程序执行的一部分,但它用于准备并发送dataflow(JobGraph)给Master(JobManager),然后,客户端断开连接或者维持连接以等待接收计算结果。
当 Flink 集群启动后,首先会启动一个 JobManger 和一个或多个的 TaskManager。由 Client 提交任务给 JobManager,JobManager 再调度任务到各个 TaskManager 去执行,然后 TaskManager 将心跳和统计信息汇报给 JobManager。TaskManager 之间以流的形式进行数据的传输。上述三者均为独立的 JVM 进程。
Client 为提交 Job 的客户端,可以是运行在任何机器上(与 JobManager 环境连通即可)。提交 Job 后,Client 可以结束进程(Streaming的任务),也可以不结束并等待结果返回。
JobManager 主要负责调度 Job 并协调 Task 做 checkpoint,职责上很像 Storm 的 Nimbus。从 Client 处接收到 Job 和 JAR 包等资源后,会生成优化后的执行计划,并以 Task 的单元调度到各个 TaskManager 去执行。
TaskManager 在启动的时候就设置好了槽位数(Slot),每个 slot 能启动一个 Task,Task 为线程。从 JobManager 处接收需要部署的 Task,部署启动后,与自己的上游建立 Netty 连接,接收数据并处理。

TaskManger(worker)与Slots 理解

在Flink job的运行过程中,Flink
Job中每一个worker(TaskManager)都是一个JVM进程,它可能会在独立的Slot(线程)上执行一个或多个subtask(子任务)。为了控制一个worker能接收多少个task,worker通过task
slot来进行控制(一个worker至少有一个task slot)。 每个task
slot表示TaskManager拥有资源的一个固定大小的子集。假如一个TaskManager有三个slot,那么它会将其管理的内存分成三份给各个slot。资源slot化意味着一个subtask将不需要跟来自其他job的subtask竞争被管理的内存,取而代之的是它将拥有一定数量的内存储备。需要注意的是,这里不会涉及到CPU的隔离,slot目前仅仅用来隔离task的受管理的内存。
通过调整task
slot的数量,允许用户定义subtask之间如何互相隔离。如果一个TaskManager一个slot,那将意味着每个task
group运行在独立的JVM中(该JVM可能是通过一个特定的容器启动的),而一个TaskManager多个slot意味着更多的subtask可以共享同一个JVM。而在同一个JVM进程中的task将共享TCP连接(基于多路复用)和心跳消息。它们也可能共享数据集和数据结构,因此这减少了每个task的负载。

图 TaskManager与Slot
 

上白书妖补充解释图:

图 TaskManager与Slot

  图 TaskManager与Slot

    子任务共享Slot

上白书妖补充解释图:

上白书妖补充图
 
 
 
 
 
 
 
 
 
 

默认情况下,Flink允许子任务共享slot,即使它们是不同任务的子任务(前提是它们来自同一个job)。
这样的结果是,一个slot可以保存作业的整个管道。 Task
Slot是静态的概念,是指TaskManager具有的并发执行能力,可以通过参数taskmanager.numberOfTaskSlots进行配置;而并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,可以通过参数parallelism.default进行配置。
也就是说,假设一共有3个TaskManager,每一个TaskManager中的分配3个TaskSlot,也就是每个TaskManager可以接收3个task,一共9个TaskSlot,如果我们设置parallelism.default=1,即运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲,因此,设置合适的并行度才能提高效率

上白书妖补充解释图
上白书妖博客
 
 
上白书妖补充图示:
上白书妖博客
 
 
 
上白书妖补充图解:TaskManager和Slot
上白书妖补充图解:TaskManager和Slot

程序与数据流(DataFlow)

上白书妖博客
 
 
上白书妖补充图解:TaskManager和Slot
上白书妖博客

所有的Flink程序都是由三部分组成的: Source 、Transformation和Sink。
Source负责读取数据源,Transformation利用各种算子进行处理加工,Sink负责输出。
在运行时,Flink上运行的程序会被映射成“逻辑数据流”(dataflows),它包含了这三部分。每一个dataflow以一个或多个sources开始以一个或多个sinks结束。dataflow类似于任意的有向无环图(DAG)。在大部分情况下,程序中的转换运算(transformations)跟dataflow中的算子(operator)是一一对应的关系,但有时候,一个transformation可能对应多个operator。

程序与数据流
 
 

执行图(ExecutionGraph)

由Flink程序直接映射成的数据流图是StreamGraph,也被称为逻辑流图,因为它们表示的是计算逻辑的高级视图。为了执行一个流处理程序,Flink需要将逻辑流图转换为物理数据流图(也叫执行图),详细说明程序的执行方式。
 
Flink 中的执行图可以分成四层:StreamGraph(数据流图) -> JobGraph(工作图) -> ExecutionGraph(执行图)-> 物理执行图。
 
StreamGraph:(数据流图)是根据用户通过 Stream API 编写的代码生成的最初的图。用来表示程序的拓扑结构有效。
JobGraph: StreamGraph经过优化后生成了 JobGraph,提交给JobManager 的数据结构。主要的优化为,将多个符合条件的节点 chain(连接)
在一起作为一个节点,这样可以减少数据在节点之间流动所需要的序列化/反序列化/传输消耗。
ExecutionGraph: JobManager 根据 JobGraph生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本,是调度层最核心的数据结构。
物理执行图: JobManager 根据 ExecutionGraph 对 Job 进行调度后,在各个TaskManager 上部署 Task
后形成的“图”,并不是一个具体的数据结构。

上白书妖博客

 
 
上白书妖补充图示解释:

上白书妖博客
上白书妖详解:
       StreamGraph称之为数据流图,数据流图是根据用户通过API的编程,尤其是通过dataStream API的编程,编程就是你写好的代码.就是根据你写好的代码来生成一个最初的图,这个图用来描述你代码或者说你程序的拓扑结构,这样的图就称之为StreamGraph(数据流图)
       举例:如图所示:
上白书妖博客
           假设我写的代码里面第一个写的是Source读数据,读完数据之后调用FlatMap,接下来调用第三个Map算子;这些完全是根据自己的代码而定的.我这里先不管代码中我Map算子设置的并行度是几或者我的FlatMap中设置的并行度是几.我就把我写好的代码根据算子调用的顺序得到上面这张图,这张图就称之为数据流图.这张数据流图就是用来展示你写的代码的拓扑结构.这张数据流图是我们看不到的,因为Web-UI界面是不会给我展示这张图的.当然,自己写代码的人自己心里面是有这样图的.然后根据我的数据流图,优化之后的到一个JobGraph,这个我们称之为工作图.
           JobGraph是什么意思呢?
           他实际上是将前面的StreamGraph(数据流图)进行优化,优化之后呢.他会把多个符合条件的节点,通过operatorChain(任务链)连在一起.他时通过任务链把多个符合条件的节点连在一起.如下图所示:
上白书妖博客
        上面两个图都是在客户端完成的,客户端完成之后就要开始要提交了.客户端提交给JobManager,JobManager在接收到你提交过来的Job之后,他首先会根据你提交过来的图,将这个图变成执行图.执行图里面有什么特点呢?他是根据你这个执行图看看你有几个管道,找到你有几个管道,每个管道之间的数据通信是什么样子的.这就是所谓的执行图.变成执行图之后,每个管道还要得到不同的任务,因为你已经得到管道了,得到管道之后你就可以得到各个不同的任务.这个每个任务在哪个Slot上运行.后面这个图就叫物理执行图了.因为物理执行图就是实施去哪个TaskManager上的Slot去运行的.所以这四个图是这么来的.
 
         Flink 中的执行图可以分成四层:
         StreamGraph(数据流图) -> JobGraph(工作图) -> ExecutionGraph (执行图)-> 物理执行图
 
上白书妖博客

 
 
 

并行度(Parallelism)

上白书妖补充:
          并行度就是在执行过程中,尤其是我们Flink的Job执行过程中,一个流(Stream)包含一个或者多个分区.由于他包含一个或多个分区,从而就造成了一个算子他就包含一个或者多个子任务.实际上这流(Stream)和算子,这两个是因果关系.就因为你这流包含了一个或者两个或者多个分区.从而造成流所对应的算子就会出现一个或者多个子任务.这些子任务在不同的Slot上运行.而且也可能是不同的物理机.或者是不同的不同的容器,彼此之间相互互不依赖地执行.但是实际上他们有依赖关系吗?实际上他们也有依赖关系的.完全没有依赖关系是不可能的,因为我们还有一个数据的依赖.因为我们的数据一定是从上一个子任务到下一个子任务的.
        一个特定的算子它到底有多少个子任务呢?就是由我们这个并行度来决定的.而并行度就是由我们parallelism来设置的.我们可以在代码的后面通过setParallelism()方法来设置并行度.也可以统一的在ENV,来设置算子的并行度.在ENV上设置算子的并行度就是所谓默认的.由于我们设置了并行度,所以就造成了两种情况.就是造成了我们的Stream和Stream之间有两种关系存在.一种是One-to-one,还有一种就是Redistributing.
 
       One-to-one:就是一个对应一个.什么情况下才是一个对应一个呢?
      如图所示:
上白书妖博客
         Redistribute:重新分配的意思,实际上就是变了.本来可能是只有一个并行度,通过一个算子之后变成了两个或者三个等并行度了
         如图所示:
上白书妖博客
目前Flink支持8种分区策略:
①GlobalPartitioner(全局分区): 数据会被分发到下游算子的第一个实例中进行处理。
②ShufflePartitioner(shuffle分区) :数据会被随机分发到下游算子的每一个实例中进行。
③RebalancePartitioner: 数据会被循环发送到下游的每一个实例中进行处理。
④RescalePartitioner :这种分区器会根据上下游算子的并行度,循环的方式输出到下游算子的每个实例。这里有点难以理解,假设上游并行度为 2,编号为 A 和 B。下游并行度为 4,编号为 1,2,3,4。那么 A 则把数据循环发送给 1 和 2,B 则把数据循环发送给 3 和 4。假设上游并行度为 4,编号为 A,B,C,D。下游并行度为 2,编号为 1,2。那么 A 和 B 则把数据发送给 1,C 和 D 则把数据发送给 2。
⑤BroadcastPartitioner :广播分区会将上游数据输出到下游算子的每个实例中。适合于大数据集和小数据集做Jion的场景。
⑥ForwardPartitioner:用于将记录输出到下游本地的算子实例。它要求上下游算子并行度一样。简单的说,ForwardPartitioner用来做数据的控制台打印。
⑦KeyGroupStreamPartitioner :Hash 分区器。会将数据按Key的Hash值输出到下游算子实例中。​​​​
⑧CustomPartitionerWrapper:用户自定义分区器。需要用户自己实现 Partitioner 接口,来定义自己的分区逻辑。
static class CustomPartitioner implements Partitioner {
@Override
public int partition(String key, int numPartitions) {
switch (key){
case “1”: return 1;
case “2”: return 2;
case “3”: return 3;
default : return 4;
}
}
}
上白书妖

      Flink程序的执行具有并行、分布式的特性。
 
      在执行过程中,一个流(stream)包含一个或多个分区(stream partition),而每一个算子(operator)可以包含一个或多个子任务(operator subtask),这些子任务在不同的线程、不同的物理机或不同的容器中彼此互不依赖地执行。
 
       一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。一般情况下,一个流程序的并行度,可以认为就是其所有算子中最大的并行度。一个程序中,不同的算子可能具有不同的并行度。
       streamEnv.setParallelism(1)//加在ENV上表示默认所有的算子平行度都是1
并行数据流

       Stream在算子之间传输数据的形式可以是one-to-one(forwarding)的模式也可以是redistributing的模式,具体是哪一种形式,取决于算子的种类。
 
       One-to-one: stream(比如在source和map operator之间)维护着分区以及元素的顺序。那意味着map 算子的子任务看到的元素的个数以及顺序跟source 算子的子任务生产的元素的个数、顺序相同,map、fliter、flatMap等算子都是one-to-one的对应关系。

  • 类似于spark中的窄依赖

      Redistributing: stream(map()跟keyBy/window之间或者keyBy/window跟sink之间)的分区会发生改变。每一个算子的子任务依据所选择的transformation发送数据到不同的目标任务。例如,keyBy() 基于hashCode重分区、broadcast和rebalance会随机重新分区,这些算子都会引起redistribute过程,而redistribute过程就类似于Spark中的shuffle过程。

  • 类似于spark中的宽依赖

 
 

任务链(Operator Chains)

上白书妖补充:
        任务链的意思就是说,我们把两个算子按照一定的条件连接在一起.形成一个统一的Task
这就是所谓的任务链.并且我们可以在图上可以看到,如下图所示:
上白书妖博客       
            这个任务链有一定的条件,首先他们的并行度要相同.所谓的并行度相同就是One-to-one,One-to-one不是说他们只有一个,而是指他们的并行度相同.第二个条件就是他们中间没有shuffle.中间没有shuffle才会通过任务链把他们合在一起.这个任务链不用我们去做的.不过呢,我们可以设置让所有的算子之间完全隔离.就算你有条件来通过这个任务链来进行合并,我们也不让你构建一个任务链.我们只要加一个disableOperatorChaining(禁用这个任务链),禁用这个任务链之后,就算你符合条件,他也不把你这两个task链在一起,形成一个统一的Task.
           但是这两种那个更好呢?当然是有任务链的更好.有任务链可以提高吞吐,减少IO操作.
           所以,大多数情况下,我这一行代码(streamEnv.disableOperatorChaining)不应该做.

        相同并行度的one to one操作,Flink这样相连的算子链接在一起形成一个task,原来的算子成为里面的一部分。将算子链接成task是非常有效的优化:它能减少线程之间的切换和基于缓存区的数据交换,在减少时延的同时提升吞吐量。链接的行为可以在编程API中进行指定。
streamEnv.disableOperatorChaining:表示所有操作算子都不构建任务链
.disableChaining() 加在其中一个算子中,表示:该算子和其他算子不一起构建任务链。它是独立的。
 
 
task与operator chains
 
 
  

结束寄语: 知识源于积累,登峰造极源于自律

皮一下

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值