大数据系列——Flink理论

概述

Flink是一个对有界和无界数据流进行有状态计算的分布式处理引擎和框架,既可以处理有界的批量数据集,也可以处理无界的实时流数据,为批处理和流处理提供了统一编程模型,其代码主要由 Java 实现,部分代码由 Scala实现。

Flink以REST资源的形式和外部进行交互,所以可以集成在所有常见的集群资源管理环境中运行,同时提供计算状态的容错及持久化机制,基于Event(事件)驱动并行化在集群中运行,理论上可以利用无限数量的CPU,内存,磁盘和网络IO,实现任意规模的计算任务。

Flink提供一系列状态功能易于维护非常大的应用程序状态,通过异步和增量检查点算法可确保对处理延迟的影响降至最低且同时保证精确语义的状态一致性。

Flink提供了诸多抽象层的API以便用户编写分布式任务:DataSet API、DataStream API、Table API等,可支持多种编程语言,例如:Java、Python、Go、Scala等。

流处理应用主要关注的维度是流数据、数据流转状态、数据延迟到达、时间、容错处理等核心内容,所以流处理框架必须要对上面几个维度进行合理支持。

Flink通过分布式存储、状态后台存储、时间语义细分、窗口机制、检查点、保存点、Stateful Stream Processing、Watermark等机制来完成流处理应用的全方位支持。

Flink核心是一个流式的数据流执行引擎,能够基于同一个Flink运行时,同时对多个Flink客户端应用提供支持流处理和批处理两种类型应用。

Flink集群遵循一主(Master)多从(Worker)的常规架构模式, 主要包括四个组成部分:Client、Master(宿主JobManager)、Worker(宿主TaskManger)、资源管理器(ResourceManager)<外部依赖>。

下面从如下几个方面介绍下其相关理论:

目录

概述

一、架构

二、核心知识点

1、核心组件

1.1、分布式存储

1.2、运行时(Core)

1.3、抽象API

1.4、集成高阶应用

1.5、组件间通讯

1.6、客户端应用

2、基本概念

2.1、JobManager (后续迭代更名为:JobMaster)

2.2、TaskManager

2.3、分发器(Dispatcher)

2.4、资源管理器(ResourceManager)

2.5、Client

2.6、状态(State)

2.9、时间语义

2.10、窗口机制

2.11、水位线(Watermark)机制

2.12、容错机制

2.13、数据倾斜

3、编程模型

3.1、Fink内存模型

3.2、数据流

3.3、数据结构

4、计算过程

5、整体运行过程

三、部署方式

四、优缺点分析

缺点

优点

五、常见应用场景

六、调优经验

七、API应用:

java平台:(1.16以上)

DoNet平台:


一、架构

二、核心知识点

1、核心组件

Flink主要有下面一些核心组件构成,包括:分布式存储、运行时(Core)、抽象API、集成应用、 组件间通讯、 客户端应用

1.1、分布式存储

支持内存和磁盘操作,提供实时计算状态后端存储、检查点及保存点后端存储等数据管理功能,支持本地文件、Kafka、 Hadoop HDFS、RocksDB等存储方式

1.2、运行时(Core)

运行时(Runtime)为Flink各类计算提供了实现,是Flink最底层也是最核心的组件。

1.3、抽象API

抽象API包括SQL & Table API、DataStream、DataSet、Stateful Stream Processing等。

SQL & Table API:支持以SQL相同语义的方式进行流处理(Table API)和批处理(SQL)且产生相同的结果。除了基本查询外, 它还支持自定义的标量函数,聚合函数以及表值函数,可以满足多样化的复杂查询需求。

DataStream:是Flink数据处理的核心API,支持处理有界和无界数据流。

DataSet:是Flink数据处理的核心API,支持处理有界数据流。

Stateful Stream Processing:是Flink最低级别的抽象通过一些Process Function对外服务,基于此可以封装一些功能即服务(FaaS)函数(是一种在无状态容器中运行的事件驱动型计算执行模式,不需要独立宿主后台,类似于函数直接调用),

具有最大的灵活性,允许开发者对于时间和状态进行细粒度的控制。

1.4、集成高阶应用

复杂事件处理(CEP):

CEP(Complex Event Processing) 是Flink提供的复杂事件处理库,支持流式处理, 是一种基于动态环境中事件流的分析技术,它可以让你在无界流或有界流中检测出特定的数据,提取数据中重要的那部分。

事件在这里通常是有意义的状态变化,通过分析事件间的关系,利用过滤、关联、聚合等技术,根据事件间的时序关系和聚合关系制定检测规则,持续地从事件流中查询出符合要求的事件序列,最终分析得到更复杂的复合事件。

机器学习计算库(ML):

ML(Machine Learning)是Flink提供的机器学习库,支持批处理。

图计算库(Gelly):

Gelly(Graph Processing)是Flink提供的图计算库,支持批处理。

1.5、组件间通讯

Flink 的所有组件都基于 Actor System 来进行通讯。Actor system是多种角色的 actor 的容器,它提供调度,配置,日志记录等多种服务,并包含一个可以启动所有 actor 的线程池,如果 actor 是本地的,则消息通过共享内存进行共享,

但如果 actor 是远程的,则通过 RPC 来传递共享消息。

ActorSystem 是 基于 akka 实现的一个通信模块,负责节点之间的通信,如 Client 和 JobManager 之间,JobManager 和 TaskManager 之间的通信;

1.6、客户端应用

是Flink的具体应用实现部分,在此进行作业定义、连接数据源、依据业务设计转换、聚合、输入、输出等操作,然后交由Flink计算,最后得到目标结果,支持本地文件、Kafka、 Hadoop HDFS、云端存储等多种形式。

2、基本概念

2.1、JobManager (后续迭代更名为:JobMaster)

JobManager 是管理节点,负责协调管理Flink作业,一个作业由一个 JobManager 来负责(一对一)。主要有下面一些职责:

a、接受Flink客户端提交的应用(Application),包括JAR、数据流图 StreamGraph(DAG),作业图JobGraph(优化过的DAG)等

b、将 JobGraph 拆封成 Task 并转化为 执行图(ExecutionGraph),包含了所有可以并发执行的任务

c、向集群资源管理器申请计算资源,调度分发计算任务(ExecutionGraph)到计算节点(TaskManager)

d、管理多个TaskManager,包括收集作业的状态信息、协调生成检查点、保存点,必要时进行故障恢复(Failover)等

e、基于ActorSystem时刻和 TaskManager 保持心跳

2.2、TaskManager

TaskManager 包括下面一些核心概念:TaskManager、Task和Sub Task、并行度、算子链、Task Slot、数据交换管理模块(Network Manager)等。

TaskManager是执行计算任务的节点,每个 TaskManager 提供一定数量的槽(Slot)。一个Flink作业一般会分布到多个 TaskManager 上执行,计算任务是在Slot上执行的,槽是最小粒度的计算资源单位。主要有下面一些职责:

a、启动时将TaskManager所辖的Slot资源向ResourceManager注册

b、和 JobManager 交互心跳

c、和其他TaskManager进行数据交换,依赖Network Manager管理

d、管理Slot并启动线程池执行JobManager分发的计算任务

e、向JobManager报给任务执行状态

f、协同 JobManager 执行检查点、保存点、状态存储、故障恢复、任务重试等管理任务

任务(Task):是一个实际执行的物理图,一个Task是Flink运行时工作的最基本的单元, Task封装了一个并行的Operator算子或者一个Operator Chain算子链。

Flink 中的执行图可以分成四层:StreamGraph ->JobGraph -> ExecutionGraph -> 物理执行图。

逻辑流图(StreamGraph): 这是根据用户通过 DataStream API 编写的代码生成的最初的 DAG 图,用来表示程序的拓扑结构。这一步一般在客户端完成。

作业图(JobGraph): StreamGraph 经过优化后生成的就是作业图(JobGraph),这是提交给 JobManager 的数据结构,确定了当前作业中所有任务的划分。

主要的优化为: 将多个符合条件的节点链接在一起 合并成一个任务节点,形成算子链,这样可以减少数据交换的消耗。JobGraph 一般也是在客 户端生成的,在作业提交时传递给 JobManager。

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

与 JobGraph 最大的区别就是按照并行度对并行子任务进行了拆分, 并明确了任务间数据传输的方式。

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

这只是具体执行层面的图,并不是一个具体的数据结构。 物理图主要就是在执行图的基础上,进一步确定数据存放的位置和收发的具体方式。有了物理图,TaskManager 就可以对传递来的数据进行处理计算了。 一共有 5 个并行子任务,最终需要 5 个线程来执行。

子任务(SubTask):是负责处理一部分数据流任务,Sub-Task强调的是并行执行相同的算子Operator或者算子链Operator Chain,经过算子操作把Task分拆成多个Sub Task。

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

包含并行子任务的数据流,就是并行数据流,它需要多个分区(stream partition)来分配并行任务。 一般情况下,一个流应用的并行度,可以认为就是其所有算子中最大的并行度,一个程序中, 不同的算子可能具有不同的并行度。

设置并行度有下面四种方式:

1)、操作算子层面(Operator Level)

在代码中的Operator中调用setParallelism(int) 方法设置

2)、执行环境层面(Execution Environment Level)

在代码中执行环境env中调用setParallelism 方法

3)、客户端层面(Client Level)

在通过flink提交任务加入 -p 参数指定并行度 或 WEB-UI中显示指定的并行度

4)、系统层面(System Level)

在flink配置文件中指定的默认并行度parallelism.default: 1

优先级:算子层面>环境层面>客户端层面>系统层面,建议采用在代码中特定的Operator显式调用setParallelism方法。

算子链(Operator Chain):将并行度(Parallelism)相同的一对一(one to one)算子操作直接链接在一起形成一个任务然后去执行。算子操作间除了一对一(one to one)的关系,还有由keyBy和并行度改变引起的重分区(Redistributing)关系。

合并Operator成为一个Operator Chain 有两个必要的条件:

1)、Operator 并行度必须一致,不能出现Redistribution

2)、one-to-one 操作的Operator数据流维护数据的顺序与分区,上游算子的操作可以直接流入下游算子

任务槽(Task Slots):

Slot 是计算资源调度的最小单位,Slot 的数量限制了 TaskManager 能够并行处理的任务数量,一个TaskManager启动时就静态的划定了Slot的数量,可以通过参数taskmanager.numberOfTaskSlots控制大小。

每一个Slot 表示在 TaskManager 上一个固定大小的计算资源,用来处理独立的子任务,如: TaskManager 的Slot为3, TaskManager 会将计算资源平均分配成3份,每个Slot独占一份,不需要跟其他的作业进行竞争内存资源。

Slot 目前仅仅用来隔离内存,不会涉及 CPU 的隔离。在具体应用时,可以将 Slot 数量配置为机器的 CPU 核心数,尽量避免不同任务之间对 CPU 的竞争,这也是开发环境默认并行度设为机器 CPU 核心数的原因。

任务槽默认开启子任务共享,Flink 是允许子任务共享 Slot 的,只要属于同一个作业,那么对于不同任务节点的并行子任务,就可以放到同一个 Slot 上执行。

如上图:所以对于第一个任务节点 source→map,它的 6 个并行子任务必须分到不同的 slot 上(如果在 同一 Slot 就没法数据并行了),而第二个任务节点 keyBy/window/apply 的并行子任务却可以和第一个任务节点共享 Slot。

Slot共享有下面两个好处:

1)、不同的任务可能耗时不一样,如果每一个任务独占一个Slot,可能某一个任务只是简单的接收数据,而另一个任务是对数据的加工处理,此时单纯接收数据的任务会浪费 Slot 中的资源,

也会导致下游任务的积压,忙的忙死,闲的闲死,此时利用了Slot共享的机制可以避免资源的浪费。

2)、允许我们保存完整的作业管道,这样一来,即使某个 TaskManager 出现故障宕机,其他节点也可以完全不受影响,作业的任务可以继续执行。

数据交换管理模块(Network Manager):

在一个运行的Flink应用Application中,它的Tasks间需要持续的交换数据,数据传递过程由 TaskManager 负责,实际就是数据交换管理模块(Network Manager)。

Network Manager组件首先从缓冲buffer中收集records,然后再以batch的形式发送,高效使用网络资源并提高吞吐量。

每个TaskManager有一组网络缓冲池(默认每个buffer是32KB),用于发送与接受数据,如发送端和接收端位于不同的TaskManager进程中,则它们需要通过操作系统的网络栈进行交流。

流应用需要以管道的模式进行数据交换,每对TaskManager会维持一个永久的TCP连接用于做数据交换。

大数据计算在计算过程中都需要对中间计算结果不停的进行“Shuffle”处理,直至计算出最终目标结果。

在shuffle连接模式下(多个sender与多个receiver),每个sender task需要向每个receiver task传递数据,此时TaskManager需要为每个receiver task都分配一个缓冲区。如下图:

在上图中,有四个sender 任务,对于每个sender,都需要有至少四个network buffer用于向每个receiver发送数据,每个receiver都需要有至少四个buffer用于接收数据。

若sender与receiver任务都运行在同一个TaskManager进程,则sender任务会将发送的条目做序列化,并存入一个字节缓冲,然后将缓冲放入一个队列,直到队列被填满;Receiver任务从队列中获取缓冲,并反序列化输入的条目,

所以,在同一个TaskManager内,任务之间的数据传输并不经过网络交互。

TaskManager之间的buffer以I/O多路复用的方式使用同一网络连接,为了提供平滑的数据管道型的数据交换,一个TaskManager必须能提供足够的缓冲,以服务所有并行的出入数据处理。

I/O多路复用是一种共享网络连接的通讯控制机制,需要操作系统层面的支持,一般三种类型:select(Windows)、poll(Linux)、epoll(Linux),其他支持的平台也都类属于这几种模式。

2.3、分发器(Dispatcher)

Dispatcher 主要负责提供一个表述性状态转移(Representational State Transfer)REST式的接口,以超文本传输协议(Hyper Text Transfer Protocal)HTTP的形式来对外提供服务,所以Flink框架可以很容易的和其他资源管理框架集成。

Dispatcher可以接收多个作业,每接收一个作业,Dispatcher都会为这个作业分配一个JobManager,同时启动一个 Web UI用来方便地展示和监控作业执行的信息。

Dispatcher 在架构中并不是必需的, 在有些部署模式下可能不会应用到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值