本篇为Flink的第四部分 Flink运行时架构,全篇参考自 尚硅谷2022版1.13系列

        整个系列的目录如下:

💚<一>Flink简介 💚<二>Flink快速上手 💚<三>Flink 部署 💚<四>Flink 运行时架构 💚<五>DataStream API 💚<六>Flink 中的时间和窗口 💚<七>处理函数 💚<八>多流转换 💚<九>状态编程 💚<十>容错机制 💚<十一>Table API 和 SQL 💚<十二>Flink CEP

        本文章会着重记录比较重要知识点和架构,略过不重要信息和一些代码等,需要全文可以到b站观看,顺便投俩币。


<四> Flink运行时架构

知识点二十一. Flink系统架构

 1.三大组件

(1)客户端(提交任务)(严格来说不是系统的一部分)

(2)TaskManager(干活的,称为Worker)

(3)JobManager(指挥的管理资源的)

2.JobManager构成和主要作用

主要作用:

JobManager 是一个 Flink 集群中任务管理和调度的核心,是控制应用执行的主进程

构成:

(1)JobMaster

         JobManager 中最核心的组件,负责处理单独的作业(Job),和具体的 Job 是一一对应的。JobMaster 接收到要执行的应用(Jar 包,数据流图dataflow graph,和作业图JobGraph),会把 JobGraph 转换成“执行图” (ExecutionGraph),它包含了所有可以并发执行的任务。 JobMaster 会向资源管理器 (ResourceManager)发出请求,申请执行任务必要的资源。

(2)资源管理器(ResourceManager)

        ResourceManager 主要负责资源的分配和管理,停掉空闲的 TaskManager,释放计算资源。资源主要是指 TaskManager 的任务槽(task slots)。任务槽就是 Flink 集群中的资源调配单元,包含 了机器用来执行计算的一组 CPU 和内存资源。每一个任务(Task)都需要分配到一个 slot 上 执行。

(3)分发器(Dispatcher)

        Dispatcher 主要负责提供一个 REST 接口,用来提交应用,并且负责为每一个新提交的作 业启动一个新的 JobMaster 组件。Dispatcher 也会启动一个 Web UI,用来方便地展示和监控作 业执行的信息。Dispatcher 在架构中并不是必需的,在不同的部署模式下可能会被忽略掉。

3.TaskManager构成和主要作用

主要作用:

        TaskManager 是 Flink 中的工作进程,负责数据流的具体计算, TaskManager可以与其他运行同一应用的 TaskManager 交换数据。启动之后,TaskManager 会向资源管理器注册它的 slots;收到资源管理器的指令后, TaskManager 就会将一个或者多个槽位提供给 JobMaster 调用,JobMaster 就可以分配任务来执 行了。

构成:

        每一个 TaskManager 都包含了一定数量的任务槽(task slots)。Slot 是资源调度的最小单位,slot 的数量限制了 TaskManager 能够并行处理的任务数量。

知识点二十二. Flink作业提交流程

1.抽象作业流程提交

        Flink 的提交流程,随着部署模式和资源管理平台的不同,会有些许变化。抽象的作业提交流程如下:

(1)客户端(App)通过分发器提供的 REST 接口,将作业提交给 JobManager。

(2)由分发器启动 JobMaster,并将作业(包含 JobGraph)提交给 JobMaster。

(3)obMaster 将 JobGraph 解析为可执行的 ExecutionGraph,得到所需的资源数量,然后 向资源管理器请求资源(slots)。

(4)资源管理器判断当前是否由足够的可用资源;如果没有,启动新的 TaskManager。

(5)TaskManager 启动之后,向 ResourceManager 注册自己的可用任务槽(slots)。

(6)资源管理器通知 TaskManager 为新的作业提供 slots

(7)TaskManager 连接到对应的 JobMaster,提供 slots。

(8)JobMaster 将需要执行的任务分发给 TaskManager。

(9)TaskManager 执行任务,互相之间可以交换数据。

2.具体提交流程--独立模式(Standalone)

        在独立模式(Standalone)下,只有会话模式和应用模式两种部署方式。两者整体来看流 程是非常相似的:TaskManager 都需要手动启动,所以当 ResourceManager 收到 JobMaster 的 请求时,会直接要求 TaskManager 提供资源。而 JobMaster 的启动时间点,会话模式是预先启 动,应用模式则是在作业提交时启动。

除去第 4 步不会启动 TaskManager,而且直接向已有的 TaskManager 要求资源, 其他步骤与抽象流程完全一致。

3.具体提交流程--Yarn会话(Session)模式

在会话模式下,我们需要先启动一个 YARN session,这个会话会创建一个 Flink 集群。启动 JobManager,而 TaskManager 可以根据需要动态地启动。在 JobManager 内 部,由于还没有提交作业,所以只有 ResourceManager 和 Dispatcher 在运行。

(1)客户端通过 REST 接口,将作业提交给分发器。

(2)分发器启动 JobMaster,并将作业(包含 JobGraph)提交给 JobMaster。

(3)JobMaster 向资源管理器请求资源(slots)。

(4)资源管理器向 YARN 的资源管理器请求 container 资源。

(5)YARN 启动新的 TaskManager 容器。

(6)TaskManager 启动之后,向 Flink 的资源管理器注册自己的可用任务槽。

(7)资源管理器通知 TaskManager 为新的作业提供 slots。

(8)TaskManager 连接到对应的 JobMaster,提供 slots。

(9)JobMaster 将需要执行的任务分发给 TaskManager,执行任务。

可见,整个流程除了请求资源时要“上报”YARN 的资源管理器,其他与抽象流程几乎完全一样。

4.具体提交流程--Yarn会话 单作业(Per-Job)模式

在单作业模式下,Flink 集群不会预先启动,而是在提交作业时,才启动新的 JobManager。

 

(1)客户端将作业提交给 YARN 的资源管理器,这一步中会同时将 Flink 的 Jar 包和配置 上传到 HDFS,以便后续启动 Flink 相关组件的容器。

(2)YARN 的资源管理器分配 Container 资源,启动 Flink JobManager,并将作业提交给 JobMaster。这里省略了 Dispatcher 组件。

(3)JobMaster 向资源管理器请求资源(slots)。

(4)资源管理器向 YARN 的资源管理器请求 container 资源。

(5)YARN 启动新的 TaskManager 容器。

(6)TaskManager 启动之后,向 Flink 的资源管理器注册自己的可用任务槽。

(7)资源管理器通知 TaskManager 为新的作业提供 slots。

(8)TaskManager 连接到对应的 JobMaster,提供 slots。

(9)JobMaster 将需要执行的任务分发给 TaskManager,执行任务。

 可见,区别只在于 JobManager 的启动方式,以及省去了分发器。当第 2 步作业提交给 JobMaster,之后的流程就与会话模式完全一样了。 

5.具体提交流程--Yarn会话 应用(Application)模式

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

知识点二十三. Flink的数据流图

        Flink 是流式计算框架。它的程序结构,其实就是定义了一连串的处理操作,每一个数据 输入之后都会依次调用每一步计算。在 Flink 代码中,我们定义的每一个处理转换操作都叫作 “算子”(Operator),所以我们的程序可以看作是一串算子构成的管道,数据则像水流一样有序 地流过。

        所有的 Flink 程序都可以归纳为由三部分构成:Source、Transformation 和 Sink。每一条数据流(dataflow)以一个或多个 source 算子开始,以一个或多个 sink 算子结束。

(1) Source 表示“源算子”,负责读取数据源。

(2) Transformation 表示“转换算子”,利用各种算子进行处理加工。

(3) Sink 表示“下沉算子”,负责数据的输出。

        在运行时,Flink 程序会被映射成所有算子按照逻辑顺序连接在一起的一张图,这被称为 “逻辑数据流”(logical dataflow),或者叫“数据流图”(dataflow graph)。数据流图类似于任意的有向无环图(DAG),这一点与 Spark 等其他框架是一致的。

知识点二十四. 并行度

        把一个算子操作,“复制”多份到多个节点, 数据来了之后就可以到其中任意一个执行。这样一来,一个算子任务就被拆分成了多个并行的 “子任务”(subtasks),再将它们分发到不同节点,就真正实现了并行计算。在 Flink 执行过程中,每一个算子(operator)可以包含一个或多个子任务(operator subtask), 这些子任务在不同的线程、不同的物理机或不同的容器中完全独立地执行。一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。

知识点二十五. 算子链

        一个数据流在算子之间传输数据的形式可以是一对一(one-to-one)的直 通 (forwarding)模式,也可以是打乱的重分区(redistributing)模式,具体是哪一种形式,取决 于算子的种类。

(1)一对一(One-to-one,forwarding) 

        数据不需要重新分区,也不需要 调整数据的顺序,“一对一”的关系。map、filter、flatMap 等算子都是这种 one-to-one 的对应关系。这种关系类似于 Spark 中的窄依赖。

(2)重分区(Redistributing)

        在这种模式下,数据流的分区会发生改变。每一个算子的子任务,会根据数据传输的策略,把数据发送到不同的下游目标任务。例如, keyBy()是分组操作,本质上基于键(key)的哈希值进行了重分区这种算子间的关系类似于 Spark 中的宽依赖。

合并算子链:并行度相同的一对一(one to one)算子操作,可以直接链接在一起形成一个 “大”的任务(task)

知识点二十六. Flink 任务调度执行图

 知识点二十七. Flink 任务和任务槽 Tasks and Task Slots

1.Flink 中每一个 worker(也就是 TaskManager)都是一个 JVM 进程,它可以启动多个独立的线程,来并行执行多个子任务(subtask)。

2.由于计算资源有限,需要在 TaskManager 上对每个任务运行所占用的资源 做出明确的划分,这就是所谓的任务槽(task slots)。任务槽(task slot)其实表示了 TaskManager 拥有计算资源的一个固定大小的子集。(教室20张桌子,大家分开坐)

3.TaskManager 只有一个 slot,意味着每个任务都会运行在独立的 JVM 中。一个 TaskManager 设置多个 slot 则意味着多个子任务可以共享同一个 JVM。(教师只有一个桌子独享黑板(JVM),坐许桌子共享黑板)

4.slot 共享机制可以将资源密集型和非密集型的任务同时放到 一个 slot 中,它们就可以自行分配对资源占用的比例,从而保证最重的活平均分配给所有的 TaskManager。

5.task slot是静态的概念 , 是 指TaskManager 具有的并发执行能力,而并行度是动态概念,也就是 TaskManager 运行程序时实际使用的并发能力。(有20张桌子可以不坐满,可以坐15个人)

更多推荐