Flink运行时架构

Flink的作业提交流程涉及客户端、JobManager、TaskManager和ResourceManager。JobManager中的JobMaster将JobGraph转换为ExecutionGraph并分配资源,TaskManager执行任务。ResourceManager负责资源分配,TaskManager提供任务槽。在不同部署环境如独立模式和YARN集群中,作业提交和资源管理有所不同,包括会话模式和应用模式的差异。
摘要由CSDN通过智能技术生成

Flink运行时架构

详细分析在不同部署环境中的作
业提交流程,深入了解 Flink 设计架构中的主要概念和原理。

系统架构

对于一个分布式系统,其中的核心问题有:集群中资源的分配和管理、进程协调调度、持久化和高可用的数据存储,以及故障恢复。

整体构成

  • Flink 的作业提交和任务处理系统
    在这里插入图片描述

  • 客户端只负责作业的提交。具体来说就是调用main方法,将代码转换为数据流图,并最终生成作业图,一并发给JobManager。

  • 我们可以在客户端选择断开与 JobManager 的连接, 也可以继续保持连接。之前我们在命令提交作业时,加上的-d 参数,就是表示分离模式(detached mode),也就是断开连接。

  • TaskManager 启动之后,JobManager 会与它建立连接,并将作业图(JobGraph)转换成可执行的“执行图”(ExecutionGraph)分发给可用的 TaskManager,然后就由 TaskManager 具体执行任务。

作业管理器(JobManager)

JobManager 是一个 Flink 集群中任务管理和调度的核心,是控制应用执行的主进程。也就是说,每个应用都应该被唯一的 JobManager 所控制执行。
在高可用(HA)的场景下,可能会出现多个 JobManager;这时只有一个是正在运行的领导节点(leader),其他都是备用节点(standby)。

  • JobMaster

    • JobMaster 是 JobManager 中最核心的组件,负责处理单独的作业(Job)。所以 JobMaster和具体的 Job 是一一对应的
    • JobMaster 会把 JobGraph 转换成一个物理层面的数据流图,这个图被叫作“执行图”(ExecutionGraph),它包含了所有可以并发执行的任务。JobMaster 会向资源管理器(ResourceManager)发出请求,申请执行任务必要的资源。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的 TaskManager 上
    • 在运行过程中,JobMaster 会负责所有需要中央协调的操作,比如说检查点(checkpoints)的协调。
  • 资源管理(ResourceManager)

    ResourceManager 主要负责资源的分配和管理,在 Flink 集群中只有一个

    • “资源”,主要是指 TaskManager 的任务槽(task slots)。任务槽就是 Flink 集群中的资源调配单元,包含了机器用来执行计算的一组 CPU 和内存资源。每一个任务(Task)都需要分配到一个 slot 上执行。
    • Flink 的 ResourceManager,针对不同的环境和资源管理平台(比如 Standalone 部署,或者YARN),有不同的具体实现。在 Standalone 部署时,因为 TaskManager 是单独启动的(没有Per-Job 模式),所以 ResourceManager 只能分发可用 TaskManager 的任务槽,不能单独启动新TaskManager。
    • 存在资源管理平台时,就不受此限制。当新的作业申请资源时,ResourceManager 会将有空闲槽位的 TaskManager 分配给 JobMaster。如果 ResourceManager 没有足够的任务槽,它还可以向资源提供平台发起会话,请求提供启动 TaskManager 进程的容器。另外,ResourceManager 还负责停掉空闲的 TaskManager,释放计算资源。
  • 分发器 (Dispatcher)

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

任务管理器(TaskManager)

TaskManager 是 Flink 中的工作进程,数据流的具体计算就是它来做的,所以也被称为“Worker”。Flink 集群中必须至少有一个 TaskManager;

  • 每一个 TaskManager 都包含了一定数量的任务槽(task slots)。Slot是资源调度的最小单位,slot 的数量限制了 TaskManager 能够并行处理的任务数量。启动之后,TaskManager 会向资源管理器注册它的 slots;收到资源管理器的指令后,TaskManager 就会将一个或者多个槽位提供给 JobMaster 调用,JobMaster 就可以分配任务来执行了。
  • 在执行过程中,TaskManager 可以缓冲数据,还可以跟其他运行同一应用的 TaskManager交换数据。

作业提交流程

高层级抽象视角

在这里插入图片描述

  • (1) 一般情况下,由客户端(App)通过分发器提供的 REST 接口,将作业提交给JobManager。
    (2)由分发器启动 JobMaster,并将作业(包含 JobGraph)提交给 JobMaster。
    (3)JobMaster 将 JobGraph 解析为可执行的 ExecutionGraph,得到所需的资源数量,然后向资源管理器请求资源(slots)。
    (4)资源管理器判断当前是否由足够的可用资源;如果没有,启动新的 TaskManager。
    (5)TaskManager 启动之后,向 ResourceManager 注册自己的可用任务槽(slots)。
    (6)资源管理器通知 TaskManager 为新的作业提供 slots。
    (7)TaskManager 连接到对应的 JobMaster,提供 slots。
    (8)JobMaster 将需要执行的任务分发给 TaskManager。
    (9)TaskManager 执行任务,互相之间可以交换数据。

独立模式(standalone)

  • 在这里插入图片描述

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

YARN 集群

  • 会话模式 (session mode)
    在这里插入图片描述

    • Yarn Session 模式下收到容器请求
      这里只启动了 JobManager,而 TaskManage可以根据需要动态地启动。在 JobManager 内部,由于还没有提交作业,所以只有 ResourceManager 和 Dispatcher 在运行

    • Yarn 集群作业提交流程

    • 在这里插入图片描述

    • (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,执行任务。

  • 单作业 (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,执行任务。
  • 应用模式(application mode)

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

一些重要概念

数据流图 (Dataflow Graph)

  • 在运行时,Flink 程序会被映射成所有算子按照逻辑顺序连接在一起的一张图,这被称为“逻辑数据流”(logical dataflow),或者叫“数据流图”(dataflow graph)。
  • 数据流图类似于任意的有向无环图(DAG),这一点与 Spark 等其他框架是一致的。图中的每一条数据流(dataflow)以一个或多个 source 算子开始,以一个或多个 sink 算子结束。
  • 调用其他转换操作之后返回的数据类型是 SingleOutputStreamOperator,说明这是一个算子操作

并行度(Parallelism)

  • 什么是并行计算

    • 没有类似Spark的DAG图
    • 如果说 Spark基于 MapReduce 架构的思想是“数据不动代码动”,那么 Flink 就类似“代码不动数据流动”,原因就在于流式数据本身是连续到来的、我们不会同时传输所有数据,这其实是更符合数据流本身特点的处理方式。
  • 并行子任务和并行度

    • 把一个算子操作,“复制”多份到多个节点,数据来了之后就可以到其中任意一个执行。这样一来,一个算子任务就被拆分成了多个并行的“子任务”(subtasks),再将它们分发到不同节点,就真正实现了并行计算。
    • 一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。
  • 并行度的设置

    • 代码中设置:(只针对当前算子有效)
      stream.map(word -> Tuple2.of(word, 1L)).setParallelism(2);
      全局设置:(一般不建议,会导致无法动态扩容)
      env.setParallelism(2);
    • 提交应用时设置: -p 参数
      bin/flink run –p 2 –c com.atguigu.wc.StreamWordCount
      ./FlinkTutorial-1.0-SNAPSHOT.jar
    • 配置文件设置: flink-conf.yaml
      parallelism.default: 2
    • 没有配置文件,默认并行度就是当前机器的 CPU 核心数

算子链(Operator Chain)

  • 算子间数据传输

    • 一对一(One-to-one,forwarding):类似于 Spark 中的窄依赖。
    • 重分区(Redistributing):类似于 Spark 中的宽依赖。
  • 合并算自链

    • 并行度相同的一对一(one to one)算子操作,可以直接链接在一起形成一个
      “大”的任务(task),这样原来的算子就成为了真正任务里的一部分。这样的技术被称为“算子链”(Operator Chain)。
    • 将算子链接成 task 是非常有效的优化:可以减少线程之间的切换和基于缓存区的数据交换,在减少时延的同时提升吞吐量。
    • 禁止算子链合并:
      // 禁用算子链
      .map(word -> Tuple2.of(word, 1L)).disableChaining();
      // 从当前算子开始新链
      .map(word -> Tuple2.of(word, 1L)).startNewChain()

作业图(JobGraph)与执行图(ExecutionGraph)

  • 逻辑图(StreamGraph)

    • 用户通过 DataStream API 编写的代码生成的最初的 DAG 图
  • 作业图(JobGraph)

    • StreamGraph 经过优化后生成的就是作业图(JobGraph),这是提交给 JobManager 的数据结构,确定了当前作业中所有任务的划分。
    • 主要的优化为: 将多个符合条件的节点链接在一起合并成一个任务节点,形成算子链,这样可以减少数据交换的消耗。JobGraph 一般也是在客户端生成的,在作业提交时传递给 JobMaster。
  • 执行图(ExecutionGraph)

    • JobMaster 收到 JobGraph 后,会根据它来生成执行图(ExecutionGraph)。ExecutionGraph
      是 JobGraph 的并行化版本,是调度层最核心的数据结构。
  • 物理图(Physical Graph)

    • JobMaster 生成执行图后, 会将它分发给 TaskManager;各个 TaskManager 会根据执行图部署任务,最终的物理执行过程也会形成一张“图”,一般就叫作物理图(Physical Graph)。

任务(Tasks)和任务槽(Task Slots)

  • 任务槽(Task Slots)

    • Flink 中每一个 worker(也就是 TaskManager)都是一个 JVM 进程,它可以启动多个独立的线程,来并行执行多个子任务(subtask)。
    • 每个任务槽(task slot)其实表示了 TaskManager 拥有计算资源的一个固定大小的子集。这些资源就是用来独立执行一个子任务的。
  • 任务槽数量的设置

    • 过集群的配置文件来设定 TaskManager 的 slot 数量:
      taskmanager.numberOfTaskSlots: 8
    • 通过调整 slot 的数量,我们就可以控制子任务之间的隔离级别。
    • slot 目前仅仅用来隔离内存,不会涉及 CPU 的隔离。在具体应用时,可以将 slot 数量配置为机器的 CPU 核心数,尽量避免不同任务之间对 CPU 的竞争。
      这也是开发环境默认并行度设为机器 CPU 数量的原因。
  • 任务对任务槽的共享

    • 默认情况下,Flink 是允许子任务共享 slot
    • 涉及大量的数据、状态存储和计算,我们一般把这类任务叫作“资源密集型”(intensive)任务
    • 1.将资源密集型和非密集型的任务同时放到一个 slot 中,它们就可以自行分配对资源占用的比例,从而保证最重的活平均分配给所有的TaskManager。
      2.某个 TaskManager出现故障宕机,其他节点也可以完全不受影响,作业的任务可以继续执行。
      3.并行子任务是不能共享 slot 的,所以允许 slot 共享之后,运行作业所需的 slot 数量正好就是作业中所有算子并行度的最大值。
    • 希望某个算子对应的任务完全独占一个 slot,或者只有某一部分算子共享 slot,设置“slot 共享组”(SlotSharingGroup)手动指定
      .map(word -> Tuple2.of(word, 1L)).slotSharingGroup(“1”);
      只有属于同一个 slot 共享组的子任务,才会开启 slot 共享;不同组之间的任务是完
      全隔离的,必须分配到不同的 slot 上。在这种场景下,总共需要的 slot 数量,就是各个 slot共享组最大并行度的总和。
  • 任务槽和并行度的关系

    • task slot 是 静 态 的 概 念 , 是 指 TaskManager 具 有 的 并 发 执 行 能 力 , 可 以 通 过 参 数taskmanager.numberOfTaskSlots 进行配置。
    • 并行度(parallelism)是动态概念,也就是TaskManager 运行程序时实际使用的并发能力,可以通过参数 parallelism.default 进行配置
    • 并行度如果小于等于集群中可用 slot 的总数,程序是可以正常执行的,因为 slot 不一
      定要全部占用,有十分力气可以只用八分;而如果并行度大于可用 slot 总数,导致超出了并行能力上限,那么心有余力不足,程序就只好等待资源管理器分配更多的资源了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值