作业管理器(JobManager)(Master节点)
• 控制⼀个应⽤程序执⾏的主进程,也就是说,每个应⽤程序都会被⼀个不同的JobManager 所控制执⾏。
• JobManager 会先接收到要执⾏的应⽤程序,这个应⽤程序会包括:作业图(JobGraph)、逻辑数据流图(logical dataflow graph)和打包了所有的类、库和其它资源的JAR包。
• JobManager 会把JobGraph转换成⼀个物理层⾯的数据流图,这个图被叫做“执⾏图” (ExecutionGraph),包含了所有可以并发执⾏的任务。
• JobManager 会向资源管理器(Flink的资源管理器)(ResourceManager)请求执⾏任务必要的资源,也就是任务管理器(TaskManager)(Slave节点)上的任务插槽(slot)。⼀旦它获取到了⾜够的资源,就会将执⾏图(DAG)分发到真正运⾏它们的TaskManager上。⽽在运⾏过程中,JobManager会负责所有需要中央协调的操作,⽐如说检查点(checkpoints)的协调。
任务管理器(TaskManager)(Slave节点)
• Flink中的⼯作进程。通常在Flink中会有多个TaskManager运⾏,每⼀个TaskManager都包含了⼀定数量的插槽(slots)。插槽的数量限制了TaskManager能够执⾏的任务数量。
• 启动之后,TaskManager会向资源管理器注册它的插槽;收到资源管理器的指令后,TaskManager就会将⼀个或者多个插槽提供给JobManager调⽤。JobManager就可以向插槽分配任务(tasks)来执⾏了。
• 在执⾏过程中,⼀个TaskManager可以跟其它运⾏同⼀Flink程序的TaskManager交换数据(⽐如shuffle)。
• 每⼀个任务管理器是⼀个JVM进程,每⼀个插槽是⼀个线程
资源管理器(ResourceManager)
• 主要负责管理任务管理器(TaskManager)的插槽(slot),TaskManager 插槽是Flink中定义的处理资源单元。
• Flink为不同的环境和资源管理⼯具提供了不同资源管理器,⽐如YARN、Mesos、Kubernetes(管理docker容器组成的集群),以及Standalone(独⽴集群)部署。
• 当JobManager申请插槽资源时,Flink的资源管理器会将有空闲插槽的TaskManager分配给JobManager。如果Flink的资源管理器没有⾜够的插槽来满⾜JobManager的请求,它还可以向Yarn的资源管理器发起会话,以提供启动TaskManager进程的容器。
分发器(Dispatcher)
• 可以跨作业运⾏,它为应⽤提交提供了RESTful接⼝(GET/PUT/DELETE/POST)。
• 当⼀个应⽤被提交执⾏时,分发器就会启动并将应⽤移交给⼀个JobManager。
• Dispatcher也会启动⼀个Web UI(localhost:8081),⽤来⽅便地展示和监控作业执⾏的信息。
• Dispatcher在架构中可能并不是必需的,这取决于应⽤提交运⾏的⽅式。
App通过WebUI分发器提交jar包以后,启动并提交的应用并行度为1会向资源管理器(ResourceManager)请求一个任务槽,当我们的任务管理器(TaskManager)节点在启动的时候,会向资源管理器(ResourceManager)去注册任务管理的任务槽,注册之后我们的资源管理器向任务管理器发出提供任务槽的指令,然后任务管理器向作业管理器(JobManager)提供任务槽,然后我们的作业管理器就可以提交要在任务槽中执行的任务,任务管理器之间会存在交换数据的方式。
跟独立集群相似性很高;Flink Client是依赖与HDFS,Flink上传jar包到HDFS中,然后Flink client会向ResourceManager以会话的方式提交Job,把jar包提交到YARN的资源管理器里,并且这个时候YARN的资源管理器会启动一个ApplicationMaster去应用主节点,这个应用主节点包含着JobManager,然后Jobmanager回去HDFS中加载我们打包好的jar以及配置,加载好根据我们的需要去启动我们的任务管理器。
白色框是Flink写的代码,写的代码会在编译的过程中去做一个优化,之后通过Actor System(异步io提高效率)把jar包提交到JobManager里,然后JobManager会把任务部署到TaskManager,每一个TaskManager有不同数量的任务槽位,这些任务槽不一定占满,比如有100个任务槽,我们设置了并行度是1,只会申请一个任务槽。并且任务管理器之间可能需要任务数据交换(分组,广播变量),JobManager还会向TaskManager每隔10s发送心跳信息,因为只有隔一段时间能确保你的节点是活着的。
• Flink 中每⼀个 TaskManager 都是⼀个JVM进程,每⼀个任务插槽都会启动⼀个线程,它可能会在独⽴的线程上执⾏⼀个或多个 subtask,每⼀个⼦任务占⽤⼀个任务插槽(Task Slot)
• 为了控制⼀个 TaskManager 能接收多少个 task, TaskManager 通过 task slot 来进⾏控制(⼀个 TaskManager ⾄少有⼀个 slot)
后期可以自己在每一个算子里重写属于自己的并行度
• 默认情况下,Flink 允许⼦任务共享 slot,即使它们是不同任务的⼦任务。 这样的结果是,⼀个 slot 可以保存作业的整个管道。
• Task Slot 是静态的概念,是指 TaskManager 具有的并发执⾏能⼒
• 所有的Flink程序都是由三部分组成的: Source 、Transformation 和 Sink。
• Source 负责读取数据源,Transformation 利⽤各种算⼦进⾏处理加⼯,Sink 负责输出
• 在运⾏时,Flink上运⾏的程序会被映射成“逻辑数据流”(dataflows),它包含了这三部分
• 每⼀个dataflow以⼀个或多个sources开始以⼀个或多个sinks结束。dataflow类似于任意的有向⽆环图(DAG)
• 在⼤部分情况下,程序中的转换运算(transformations)跟dataflow中的算⼦(operator)是⼀⼀对应的关系
• Flink 中的执⾏图可以分成四层:StreamGraph -> JobGraph -> ExecutionGraph -> 物理执
⾏图
➢ StreamGraph(写的代码):是根据⽤户通过 Stream API 编写的代码⽣成的最初的图。⽤
来表示程序的拓扑结构。
➢ JobGraph:StreamGraph在编译的阶段经过优化后⽣成了 JobGraph,提交给 JobManager
的数据结构。主要的优化为,将多个符合条件(窄依赖,没有shuffle)的算⼦ chain 在⼀起
作为⼀个节点
➢ ExecutionGraph:JobManager 根据 JobGraph ⽣成ExecutionGraph。ExecutionGraph是
JobGraph的并⾏化版本,是调度层最核⼼的数据结构。
➢ 物理执⾏图:JobManager 根据 ExecutionGraph 对 Job 进⾏调度后,在各个TaskManager
上部署 Task 后形成的“图”,并不是⼀个具体的数据结构。
• ⼀个特定算⼦的⼦任务(subtask)的个数被称之为其并⾏度(parallelism)。⼀般情况下,⼀个 stream 的并⾏度,可以认为就是其所有算⼦中最⼤的并⾏度。
• ⼀个程序中,不同的算⼦可能具有不同的并⾏度
• 算⼦之间传输数据的形式可以是 one-to-one (forwarding) 的模式也可以是redistributing 的模式,具体是哪⼀种形式,取决于算⼦的种类
➢ One-to-one:stream维护着分区以及元素的顺序(⽐如source和map之间)。这意味着map 算⼦的⼦任务看到的元素的个数以及顺序跟 source 算⼦的⼦任务⽣产的元素的个数、顺序相同。map、filter、flatMap等算⼦都是one-to-one的对应关系。
➢ Redistributing:stream的分区会发⽣改变。每⼀个算⼦的⼦任务依据所选择的transformation发送数据到不同的⽬标任务。例如,keyBy 基于 hashCode 重分区、⽽broadcast 和 rebalance 会随机重新分区,这些算⼦都会引起redistribute过程,⽽redistribute 过程就类似于 Spark 中的 shuffle 过程。
• Flink 采⽤了⼀种称为任务链的优化技术,可以在特定条件下减少本地通信的开销。为了满⾜任务链的要求,必须将两个或多个算⼦设为相同的并⾏度,并通过本地转发(local forward)的⽅式进⾏连接
• 相同并⾏度的 one-to-one 操作,Flink 这样相连的算⼦链接在⼀起形成⼀个 task,原来的算⼦成为⾥⾯的 subtask
• 并⾏度相同、并且是 one-to-one 操作,两个条件缺⼀不可
A的并行度是4,B的并行度是4,C的并行度是2,D的并行度是4,E的并行度是2,首先A和B之间可以串成一个节点放在同一个任务槽,因为他俩是向前发送并且并行度一样,C和D之间并行度不一样,并且存在Shuffle的,所以C会把数据放到其中两个并行度里,D算子并行度为4,E的并行度为2,所以D会占用4个任务槽传输到E上(并行度多少任务槽就放多少,而且是随机位置放任务槽中;最大并行度就等于任务槽数量)