栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > 架构设计

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

架构设计 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【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、抽象视角

( 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 )下,只有会话模式和应用模式两种部署方式。 3、Yarn集群模式

 (1)会话模式

 (2)单作业模式

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 ),这些子任务在不同的线程、不同的物理机或不同的容器中完全独立地执行。

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

( 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 中,并行度相同的一对一 算子操作,可以直接链接在一起形成一个 “大”的任务,这样原来的算子就成为了真正任务里的一部分。好处:可以减少线程之间的切换和基于缓存区的数据交换,在减少时延的同时提升吞吐量。

 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 数量的原因。 任务对任务槽的共享: 每个任务节点的并行子任务一字排开,占据不同的 slot ;而不同的任务节点的子任务可以共享 slot

 

任务槽与并行度的关系:

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

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/907050.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号