Flink的基础理论系统架构介绍
|0x00 如何进行批量数据的流处理
Flink将批处理当做是流处理的一种特殊形式,即数据流是有限度的,处理的方法与流处理也基本相似,但存在一些区别:
(一)不再使用检查点机制:由于数据集是有限的,因此容错机制可以通过重跑全部数据的形式来实现。尽管这样做会显著增加容错的代价,但由于实现方式非常简单,避免了可能存在的潜在问题。
(二)有状态操作(Stateful Operations)被极大的简化,使用了简单的内存操作及非核心数据结构来实现,而不是key/value键值对的形式。
(三)引入了只有在批处理时才使用的同步迭代机制。
|0x01 任务及操作链
Flink在分布式状态下,会将算子(Operator)的子任务(Subtask)链接作为任务(Task)。每个任务(Task)在单独的线程中运行,能够减少线程之间的切换、减少消息的序列化/反序列化、减少数据在缓冲区的交换、减少了延迟的同时提高整体的吞吐量。相关图示如下:
|0x02 分布式进程
Flink分布式环境包括两大进程:
(一)JobManagers,又称为Masters,用于协调分布式执行机制,包括分布式环境下的任务、检查点、容错机制等。JobManager最少要有1个,高可用性场景下要求有多个。多个JobManager中只有一个是Leader,其余的是备用进程。
(二)TaskManagers,用于执行数据流中的具体任务(Task)和子任务(Subtask),TaskManager至少应该有1个。
当Flink集群启动后,首先会启动一个JobManger和多个的TaskManager。由Client提交任务给JobManager,JobManager再调度任务到各个TaskManager去执行,然后TaskManager将心跳和统计信息汇报给JobManager。
分布式进程图式如下:
|0x03 线程槽位与资源
每一个TaskManager是一个JVM进程,能够执行一个或多个子任务(Subtask)的线程,这些线程由线程槽位(Task Slots)控制。在TaskManager下,每个Task Slot分配了固定的资源,主要是内存资源,不涉及CPU资源。假如TaskManager包括了三个Task Slot,每个Task Slot都将分配到1/3的内存资源。图示如下:
在默认情况下,Flink允许子任务(Subtask)共享单元内的资源给不同类型的任务,只要这些不同类型的任务都是在同一个Job下,这样做有两个好处:
(一)每个Flink的节点都可以尽可能多的运行job任务,不需要计算它们总共需要多少资源。
(二)能够最大化的利用系统资源,提升数据流计算的并行度,并且确保繁荣的子任务(Subtask)能够公平的分布在TaskManager中。
以上图为例,通过槽位共享机制,并行度能够从2提升到了6,如下图所示:
|0xFF 后端状态
当我们启动了检查点机制时,流处理中的相关状态(State)信息将被后端持久化,具体后端以何种方式存储,将决定持久化的方式和位置。例如可以选择在内存中存储HashMap,也可以选择通过RocksDB的方式存储键值对。图示如下: