Flink-基本概述

Flink基本概述

  • Flink是什么
  • Flink架构
  • Flink组件
  • Flink基石
  • 并行度
    • 如何设置并行度
    • TaskManager和Slots
  • 程序与数据流
  • 数据传输形式
  • 任务链
  • 特性总结

flink基本概念,其实通过阅读官网可以更好的理解flink : https://flink.apache.org/zh/flink-architecture.html

说明:本文是作者本人学习flink过程中所记录和摘抄的一些笔记,如果有觉得不对的地方,欢迎留言吐槽纠正

Flink是什么

Apache Flink 是一个框架和分布式处理引擎,用于在无边界有边界数据流上进行有状态的计算。

作用:处理无界和有界数据

  • 无界流 有定义流的开始,但没有定义流的结束。它们会无休止地产生数据。无界流的数据必须持续处理,即数据被摄取后需要立刻处理。我们不能等到所有数据都到达再处理,因为输入是无限的,在任何时候输入都不会完成。处理无界数据通常要求以特定顺序摄取事件,例如事件发生的顺序,以便能够推断结果的完整性。

  • 有界流 有定义流的开始,也有定义流的结束。有界流可以在摄取所有数据后再进行计算。有界流所有数据可以被排序,所以并不需要有序摄取。有界流处理通常被称为批处理
    Flink-基本概述_第1张图片
    Apache Flink 擅长处理无界和有界数据集 精确的时间控制和状态化使得 Flink 的运行时(runtime)能够运行任何处理无界流的应用。有界流则由一些专为固定大小数据集特殊设计的算法和数据结构进行内部处理,产生了出色的性能。

Flink架构

Flink-基本概述_第2张图片
至下而上:

  • Deploy(部署):Flink 支持本地运行、能在独立集群或者在被 YARN 或 Mesos 管理的集群上运行, 也能部署在云上,即一共有三种部署模式:本地部署、Yarn模式、远程模式。
  • Runtim(运行):Flink 的核心是分布式流式数据引擎,意味着数据以一次一个事件的形式被处理。
  • API:DataStream、DataSet、Table、SQL API。
  • 拓展库:Flink 还包括用于复杂事件处理,机器学习,图形处理和 Apache Storm 兼容性的专用代码库。

Flink组件

Flink-基本概述_第3张图片
Flink运行时架构主要包括四个不同的组件,它们会在运行流处理应用程序时协同工作:作业管理器(JobManager)、资源管理器(ResourceManager)、任务管理器(TaskManager),以及分发器(Dispatcher)。因为Flink是用Java和Scala实现的,所以所有组件都会运行在Java虚拟机(JVMs)上。每个组件的职责如下:

  • 作业管理器(JobManager)是控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的作业管理器所控制执行。作业管理器会先接收到要执行的应用程序。这个应用程序会包括:作业图(JobGraph)、逻辑数据流图(logical dataflow graph)和打包了所有的类、库和其它资源的JAR包。作业管理器会把JobGraph转换成一个物理层面的数据流图,这个图被叫做“执行图”(ExecutionGraph),包含了所有可以并发执行的任务。作业管理器会向资源管理器(ResourceManager)请求执行任务必要的资源,也就是任务管理器(TaskManager)上的插槽(slot)。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的TaskManager上。而在运行过程中,作业管理器会负责所有需要中央协调的操作,比如说检查点(checkpoints)的协调。
  • ResourceManager主要负责管理任务管理器(TaskManager)的插槽(slot),TaskManger插槽是Flink中定义的处理资源单元。Flink为不同的环境和资源管理工具提供了不同资源管理器(ResourceManager),比如YARN、Mesos、K8s,以及standalone部署。当作业管理器申请插槽资源时,ResourceManager会将有空闲插槽的TaskManager分配给作业管理器。如果ResourceManager没有足够的插槽来满足作业管理器的请求,它还可以向资源提供平台发起会话,以提供启动TaskManager进程的容器。另外,ResourceManager还负责终止空闲的TaskManager,释放计算资源。
  • 任务管理器(TaskManager)是Flink中的工作进程。通常在Flink中会有多个TaskManager运行,每一个TaskManager都包含了一定数量的插槽(slots)。插槽的数量限制了TaskManager能够执行的任务数量。启动之后,TaskManager会向资源管理器注册它的插槽;收到资源管理器的指令后,TaskManager就会将一个或者多个插槽提供给作业管理器调用。作业管理器就可以向插槽分配任务(tasks)来执行了。在执行过程中,一个TaskManager可以跟其它运行同一应用程序的TaskManager交换数据。任务的执行和插槽的概念会在“任务执行”一节做具体讨论。
  • 分发器(Dispatcher)可以跨作业运行,它为应用提交提供了REST接口。当一个应用被提交执行时,分发器就会启动并将应用移交给一个作业管理器。由于是REST接口,所以Dispatcher可以作为集群的一个HTTP接入点,这样就能够不受防火墙阻挡。Dispatcher也会启动一个Web UI,用来方便地展示和监控作业执行的信息。Dispatcher在架构中可能并不是必需的,这取决于应用提交运行的方式。
    Flink-基本概述_第4张图片

Flink基石

Flink最重要的四个基石:Checkpoint、State、Time、Window。
Flink-基本概述_第5张图片
Checkpoint

checkpoint机制是Flink可靠性的基石,可以保证Flink集群在某个算子因为某些原因(如 异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保 证应用流图状态的一致性。Flink的checkpoint机制原理来自“Chandy-Lamport algorithm”算法。 (分布式快照算法)

State

flink中的状态机制,flink天生支持state,state可以认为程序的中间计算结果或者是历史计算结果;

Time

flink中支持基于事件时间和处理时间进行计算,spark streaming只能按照process time进行处理;基于事件时间的计算我们可以解决数据迟到和乱序等问题。

Window

另外流计算中一般在对流数据进行操作之前都会先进行开窗,即基于一个什么样的窗口上做这个计算。Flink提供了开箱即用的各种窗口,比如滑动窗口、滚动窗口、会话窗口以及非常灵活的自定义的窗口。

并行度

一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。

一般情况下,一个stream的并行度,可以认为就是其所以算子中最大的并行度。
Flink-基本概述_第6张图片

如何设置并行度

Apache Flink支持在不同的级别设置并行度。配置文件、env级别、算子级别。

  • 配置文件默认 在我们提交一个Job的时候如果没有考虑并行度的话,那么Flink会使用默认配置文件中的并行度。我们可以通过命令查看Flink配置文件的并行度。
$ cat flink-conf.yaml |grep "parallelism.default"
parallelism.default: 1

例如当前获取到的并行度为1。也就是说当你不设置并行度的时候它就会使用配置文件默认的并行度 1

  • env级别 env的级别就是Environment级别。也就是通过Execution Environment来设置整体的Job并行度。
val env = Stream...
env.setParallelism(5)
  • 客户端级别 如果在执行Job时候,发现代码中没有设置并行度而又不修改配置文件的话,可以通过Client来设置Job的并行度。
./bin/flink run -p 5 ../wordCount-java*.jar

-p即设置WordCount的Job并行度为5。

  • 算子级别 我们在编写Flink项目时,可能对于不同的Operator设置不同的并行度,例如为了实现读取Kafka的最高效读取需要参考Kafka的partition的数量对并行度进行设置,在Sink时需要对于Sink的介质设置不同的并行度。这样就会存在一个Job需要有多个并行度。这样就需要用到算子级别的并行度设置
val env = Stream...
val text = ...
text.keyBy(XXX)
    .flatMap(XXX).setParallelism(5)  //计算时设置为5
    .addSink(XXXXX).setParallelism(1) //写入数据库时候设置为1

并行度的高级别会覆盖低级别的配置。例如在算子中设置的策略会覆盖配置文件中的parallelism

从优先级上来看: 算子级别 > env级别 > Client级别 > 系统默认级别

在实际的使用中,我们需要设置合理的并行度来保证数据的高效处理,在一般情况下例如source,Sink等可能会需要不同的并行度来保证数据的快速读取与写入负载等。

TaskManager和Slots

Flink-基本概述_第7张图片

  • flink中每一个TaskMananger都是一个JVM进程,它可能会在独立的线程上执行一个或者多个子任务
  • 为了控制一个TaskManager能接受多少个task,TaskManager通过task slot来进行控制(一个TaskManager至少有一个slot)
  • slot就是执行一个任务所需的资源,slot之间是相互隔离的。一般根据taskManager的CPU的核心数量来设置slot的数量,如果超过这个数,也就意味着slot需要去争抢CPU

Flink-基本概述_第8张图片

  • 默认情况下,Flink允许子任务共享slot,即使它们是不同任务的子任务。这样的结果是,一个slot可以保存作业的整个管道。

  • Task Slot是静态的概念,是指TaskManager具有的并发执行能力

  • 共享slot的前提是,任务的发生或者是执行是先后关系的,才能共享同一个slot,就比如说Source map,两者的执行关系是先执行source在执行map,所以他们可以共享同一个slot。但是两个Source则必须得在两个slot中并行执行,否则slot的存在将毫无意义,因为slot的目的就是实现任务的并行执行,两个source共享一个slot就会争抢CPU资源。

  • 共享的好处,可以分摊其他slot的压力,充分利用slot的能力,假如说slot不能共享,那么执行量少的slot就特别闲,执行量大的slot又忙不过来,会出现任务堆积

  • 设置共享组

    data.slotSharingGroup("组的名称")
    

    在同一个组的任务可以共享同一个 slot,不同组必须占用不同的slot

    如果前面操作任务设置了,后面的操作没有设置共享组,则后面的操作默认跟前面的操作为同一个组

    如果都没有设置则是全部默认default组
    Flink-基本概述_第9张图片

  • Task Slot是静态的概念,是指TaskManager具有的并发执行能力,可以通过参数taskmanager.numberOfTaskSlots进行配置.并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,可以通过参数parallelism.default进行配置。

  • 也就是说,假设一共有3个TaskManager,每一个TaskManager中的分配3个TaskSlot,也就是每个TaskManager可以接收3个task,一共9个TaskSlot,如果我们设置parallelism.default=1,即运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲,因此,设置合适的并行度才能提高效率。

程序与数据流

Flink-基本概述_第10张图片

  • 所有的Flink程序都是由三部分组成的:Source、Transformation和Sink
  • Source负责读取数据源,Transformation利用各种算子进行处理加工,Sink负责输出
  • 在运行时,Flink上运行的程序会被映射成“逻辑数据流”(dataflows),它包含了这三个部分
  • 每一个dataflow以一个或者多个source开始,以一个或者多个sinks结束。dataflow类似于任意的有向无环图(DAG)
  • 在大部分情况下,程序中的转换运算(transformation)跟dataflow中的算子(operator)是一一对应的关系

数据传输形式

  • 一个程序中,不同的算子可能具有不同的并行度
  • 算子之间传输数据的形式可以是one-to-one(forwarding)的模式,也可以是redistributing的模式,具体是哪一种形式,取决于算子的种类

One-to-one

stream维护着分区以及元素的顺序(比如source和map之间)。

这意味着map算子的子任务看到的元素的个数以及顺序跟source算子的子任务生产的元素的个数、顺序相同。map、fliter、flatMap等算子都是one-to-one的对应关系。

redistributing

stream的分区会发生改变。每一个算子的子任务依据所选择的transformation发送数据到不同的目标任务。例如,keyby基于hashCode重分区,而broadcast和Rebalance会随机重新分区,这些算子都会引起redistribute过程,而redistribute过程就类似于Spark中的shuffle过程

任务链

  • Flink采用了一种称为任务链的优化技术,可以在特定条件下减少本地通信的开销。为了满足任务链的要求,必须将两个或者多个算子设为相同的并行度,并通过本地转发(local forward)的方式进行连接
  • 相同的并行度的ono-to-one操作,flink这样相连的算子连接在一起形成一个task,原来的算子成为里面的subtask
  • 并行度相同,并且是one-to-one操作,两个条件缺一不可

特性总结

  • 有状态计算的Exactly-once语义。状态是指flink能够维护数据在时序上的聚类和聚合,同时它的checkpoint机制
  • 支持带有事件时间(event time)语义的流处理和窗口处理。事件时间的语义使流计算的结果更加精确,尤其在事件到达无序或者延迟的情况下。
  • 支持高度灵活的窗口(window)操作。支持基于time、count、session,以及data-driven的窗口操作,能很好的对现实环境中的创建的数据进行建模。
  • 轻量的容错处理( fault tolerance)。 它使得系统既能保持高的吞吐率又能保证exactly-once的一致性。通过轻量的state snapshots实现
  • 支持高吞吐、低延迟、高性能的流处理
  • 支持savepoints 机制(一般手动触发)。即可以将应用的运行状态保存下来;在升级应用或者处理历史数据是能够做到无状态丢失和最小停机时间。
  • 支持大规模的集群模式,支持yarn、Mesos。可运行在成千上万的节点上
  • 支持具有Backpressure功能的持续流模型
  • Flink在JVM内部实现了自己的内存管理
  • 支持迭代计算
  • 支持程序自动优化:避免特定情况下Shuffle、排序等昂贵操作,中间结果进行缓存

你可能感兴趣的:(学习笔记,flink,学习,大数据,java,数据仓库)