【Flink】Flink的系统架构、作业提交以及一些重要概念

一、系统架构

1、整体构成

【Flink】Flink的系统架构、作业提交以及一些重要概念_第1张图片

客户端并不是处理系统的一部分,它只负责作业的提交。具体来说,就是调用程序的 main 方法,将代码转换成“数据流图”(Dataflow Graph),并最终生成作业图(JobGraph),一并发送给 JobManager

JobManager TaskManagers 可以以不同的方式启动:
(1)作为独立( Standalone )集群的进程,直接在机器上启动
(2)在容器中启动
(3)由资源管理平台调度启动,比如 YARN K8S
2、JobManager
JobManager 是一个 Flink 集群中任务管理和调度的核心,是控制应用执行的主进程。所以 JobMaster和具体的 Job 是一一对应的,多个 Job 可以同时运行在一个 Flink 集群中, 每个 Job 都有一个自己的 JobMaster。 JobManger 又包含 3 个不同的组件:
(1)JobMaster 会把 JobGraph 转换成“执行图” ,它包含了所有可以并发执行的任务。 JobMaster 会向资源管理器发出请求,申请执行任务必要的资源。一旦它获取到了足够的资源,就会 将执行图分发到真正运行它们的TaskManager 上。
(2)ResourceManager 主要负责资源的分配和管理,在 Flink 集群中只有一个。所谓“资源”, 主要是指 TaskManager 的任务槽( task slots )。任务槽就是 Flink 集群中的资源调配单元,包含 了机器用来执行计算的一组 CPU 和内存资源。每一个任务( Task )都需要分配到一个 slot 上执行。
(3) 分发器(Dispatcher) :主要负责提供一个 REST 接口,用来提交应用,并且负责为每一个新提交的作业启动一个新的 JobMaster 组件。
3、任务管理器(TaskManager)
TaskManager Flink 中的工作进程,数据流的具体计算就是它来做的,所以也被称为 “Worker ”。
每一个 TaskManager 都包含了一定数量的任务槽( task slots )。 Slot 是资源调度的最小单位,slot 的数量限制了 TaskManager 能够并行处理的任务数量。

二、作业提交流程

1、抽象视角

【Flink】Flink的系统架构、作业提交以及一些重要概念_第2张图片

1 ) 一般情况下,由客户端( App )通过分发器提供的 REST 接口,将作业交给JobManager。
(2)由分发器启动 JobMaster ,并将作业(包含 JobGraph )提交给 JobMaster
(3) JobMaster JobGraph 解析为可执行图,得到所需的资源数量,然后向ResourceManager请求资源(slots)。
(4)资源管理器判断当前是否由足够的可用资源;如果没有,启动新的 TaskManager
(5) TaskManager 启动之后,向 ResourceManager 注册自己的可用任务槽( slots )。
(6)资源管理器通知 TaskManager 为新的作业提供 slots
(7) TaskManager 连接到对应的 JobMaster ,提供 slots
(8) JobMaster 将需要执行的任务分发给 TaskManager
(9) TaskManager 执行任务,互相之间可以交换数据。
2、独立模式(Standalone
在独立模式( Standalone )下,只有会话模式和应用模式两种部署方式。
【Flink】Flink的系统架构、作业提交以及一些重要概念_第3张图片
3、Yarn集群模式

 (1)会话模式【Flink】Flink的系统架构、作业提交以及一些重要概念_第4张图片

 (2)单作业模式

【Flink】Flink的系统架构、作业提交以及一些重要概念_第5张图片YARN 的资源管理器分配 Container 资源,启动 Flink JobManager,并将作业提交给 JobMaster。这里省略了 Dispatcher 组件。

(3)应用模式

应用模式与单作业模式的提交流程非常相似,只是初始提交给 YARN 资源管理器的不再是具体的作业,而是整个应用。一个应用中可能包含了多个作业,这些作业都将在 Flink 集群中启动各自对应的 JobMaster

三、一些重要的概念

1、数据流图
Flink 代码中,我们定义的每一个处理转换操作都叫作 “算子 Operator ),所以我们的程序可以看作是一串算子构成的管道,数据则像水流一样有序地流过。
在运行时, Flink 程序会被映射成所有算子按照逻辑顺序连接在一起的一张图,这被称为 “逻辑数据流 logical dataflow ),或者叫 数据流图 dataflow graph)。在大部分情况下, dataflow 中的算子,和程序中的转换运算是一一对应的关系。
所有的 Flink 程序都可以归纳为由三部分构成: Source Transformation Sink
Source 表示 源算子 ,负责读取数据源。
Transformation 表示 转换算子 ,利用各种算子进行处理加工。
Sink 表示 下沉算子 ,负责数据的输出。
2、并行度(Parallelism
我们把一个算子操作“复制”多份到多个节点, 数据来了之后就可以到其中任意一个执行。这样一来,一个算子任务就被拆分成了多个并行的 “子任务”(subtasks ),再将它们分发到不同节点,就真正实现了并行计算。 在 Flink 执行过程中,每一个算子( operator )可以包含一个或多个子任务( operator subtask ),这些子任务在不同的线程、不同的物理机或不同的容器中完全独立地执行。
【Flink】Flink的系统架构、作业提交以及一些重要概念_第6张图片

 并行度设置方法的优先级如下:

1 )对于一个算子,首先看在代码中是否单独指定了它的并行度,这个特定的设置优先级最高,会覆盖后面所有的设置。
(2)如果没有单独设置,那么采用当前代码中执行环境全局设置的并行度。
(3)如果代码中完全没有设置,那么采用提交时 -p 参数指定的并行度。
(4)如果提交时也未指定 -p 参数,那么采用集群配置文件中的默认并行度。
3、算子链(Operator Chain
一个数据流在算子之间传输数据的形式可以是一对一( one-to-one )的直通 (forwarding) 模式,也可以是打乱的重分区( redistributing )模式
1 )一对一( One-to-one forwarding :类似窄依赖,如map、flatMap、filter
(2)重分区( Redistributing ):类似宽依赖,如keyBy、window
合并算子链:在 Flink 中,并行度相同的一对一 算子操作,可以直接链接在一起形成一个 “大”的任务,这样原来的算子就成为了真正任务里的一部分。好处:可以减少线程之间的切换和基于缓存区的数据交换,在减少时延的同时提升吞吐量。
【Flink】Flink的系统架构、作业提交以及一些重要概念_第7张图片

 Source 和 map 之间满足了算子链的要求,所以可以直接合并在一起,形成了一个任务;因为并行度为 2,所以合并后的任务也有两个并行子任务。这样,这个数据流图所表示的作业最终会有 5 个任务,由 5 个线程并行执行。

4、不同层级的图

Flink 中任务调度执行的图,按照生成顺序可以分成 四层:
                                        逻辑流图 → 作业图 → 执行图 → 物理图
(1)逻辑流图(StreamGraph
这是根据用户通过 DataStream API 编写的代码生成的最初的 DAG ,用来表示程序的拓扑结构。这一步一般在客户端完成。
(2)作业图(JobGraph
StreamGraph 经过优化后生成的就是作业图( JobGraph ),这是提交给 JobManager 的数据
结构,确定了当前作业中所有任务的划分。主要的优化为 : 将多个符合条件的节点链接在一起
合并成一个任务节点,形成算子链,这样可以减少数据交换的消耗。 JobGraph 一般也是在客
户端生成的,在作业提交时传递给 JobMaster
(3)执行图(ExecutionGraph
JobMaster 收到 JobGraph 后,会根据它来生成执行图( ExecutionGraph )。 ExecutionGraph
JobGraph 的并行化版本,是调度层最核心的数据结构。
(4)物理图(Physical Graph
JobMaster 生成执行图后, 会将它分发给 TaskManager ;各个 TaskManager 会根据执行图
部署任务,最终的物理执行过程也会形成一张“图”,一般就叫作物理图。
5、任务与任务槽
Flink 中每一个 worker( 也就是 TaskManager) 都是一个 JVM 进程,它可以启动多个独立的线程,来并行执行多个子任务(subtask)。所以如果想要执行 5 个任务,并不一定非要 5 个TaskManager,我们可以让 TaskManager 多线程执行任务。
为了控制并发量,我们需要在 TaskManager 上对每个任务运行所占用的资源做出明确的划分,这就是所谓的任务槽(task slots)。每个任务槽(task slot)其实表示了 TaskManager 拥有计算资源的一个固定大小的子集。这些资源就是用来独立执行一个子任务的。
如果一个 TaskManager 只有一个 slot ,那将意味着每个任务都会运行在独立的 JVM 中 ;而一个 TaskManager 设置多个 slot 则意味着多个子任务可以共享同一个 JVM
需要注意的是, slot 目前仅仅用来隔离内存,不会涉及 CPU 的隔离。在具体应用时,可
slot 数量配置为机器的 CPU 核心数,尽量避免不同任务之间对 CPU 的竞争。这也是开发
环境默认并行度设为机器 CPU 数量的原因。
【Flink】Flink的系统架构、作业提交以及一些重要概念_第8张图片
任务对任务槽的共享:
每个任务节点的并行子任务一字排开,占据不同的 slot ;而不同的任务节点的子任务可以共享 slot
【Flink】Flink的系统架构、作业提交以及一些重要概念_第9张图片

 

任务槽与并行度的关系:

任务槽是 静 态 的 概 念 , 是 指 TaskManager 具 有 的 并 发 执 行 能 力 , 可 以 通 过 参 数
taskmanager.numberOfTaskSlots 进行配置;而并行度( parallelism )是动态概念,也就是
TaskManager 运行程序时实际使用的并发能力,可以通过参数 parallelism.default 进行配置。
整个流处理程序的并行度,就应该是所有算子并行度中最大的那个, 这代表了运行程序需要的 slot 数量。

 

你可能感兴趣的:(Flink,flink,大数据,big,data,分布式)