Apache Flink 概述
这是我参与「第四届青训营 」笔记创作活动的的第2天
批处理
所谓 批处理 是指把一项数据处理任务先分解成更小粒度的任务,把这些任务分布在集群中的各台实例上进行计算,之后把各实例上的计算结果重新计算和组合成最终结果。批处理系统通常会操作大量的静态的数据,并等到这些数据全部处理完成后才能得到返回的结果。
批处理方式使用的数据集通常有以下特征:
- 有界:批处理数据集代表数据的有限集合
- 持久:数据通常始终存储在某种类型的持久存储位置中
- 大量:批处理操作通常是处理极为海量数据集的唯一方法
流处理
流处理 方式会随时对进入系统的数据进行实时的计算,这种模式不需要针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作。流处理中的数据集是 无边界 的,这就产生了几个重要的影响:
- 完整数据集只能代表截至目前已经进入到系统中的数据总量。
- 工作数据集也许更相关,在特定时间只能代表某个单一数据项。
- 处理工作是基于事件的,除非明确停止否则没有“尽头”。处理结果立刻可用,并会随着新数据的抵达继续更新。
混合处理
在大数据处理技术中流派中,除了单纯的批处理和流处理模式之外,还有一些处理框架既可以进行批处理也可以进行流处理,我们称之为混合处理框架。虽然专注于一种处理方式可能非常适合特定场景,但是混合框架为数据处理提供了通用的解决方案。这些框架可以用相同或相关的组件和 API 处理两种类型的数据,借此让不同的处理需求得以简化。混合处理框架中目前比较著名的就是 Spark 和 Flink 。
为什么 Flink 会脱颖而出
完全一次保证:故障后应正确恢复有状态运算符中的状态;
低延迟:越低越好。许多应用程序需要亚秒级延迟;
高吞吐量:随着数据速率的增长,通过管道推送大量数据至关重要;
强大的计算模型:框架应该提供一种编程模型,该模型不限制用户并允许各种各样的应用程序在没有故障的情况下,容错机制的开销很低;
流量控制:来自慢速算子的反压应该由系统和数据源自然吸收,以避免因消费者缓慢而导致崩溃或降低性能;
乱序数据的支持:支持由于其他原因导致的数据乱序达到、延迟到达后,计算出正确的结果;
完备的流式语义:支持窗口等现代流式处理语义抽象;
Google Dataflow Model 的开源引擎实现。
Apache Flink 开源生态
Apache Flink 在开源生态上的能力比较强大,可以支持:
流批一体:支持流式计算和批式计算;
OLAP:Flink 可以支持 OLAP 这种短查询场景;
Flink ML:pyFlink、ALink、AIFlow 等生态支持 Flink 在 ML 场景的应用;
Gelly:图计算;
Stateful Function:支持有状态的 FAAS 场景;
Flink 整体架构
Flink 分层架构
-
SDK 层:Flink's APIs Overview;
-
执行引擎层(Runtime 层):执行引擎层提供了统一的 DAG,用来描述数据处理的 Pipeline,不管是流还是批,都会转化为 DAG 图,调度层再把 DAG 转化成分布式环境下的 Task,Task 之间通过 Shuffle 传输数据;
- 调度:Jobs and Scheduling;
- Task 生命周期:Task Lifecycle;
- Flink Failover 机制:Task Failure Recovery;
- Flink 反压概念及监控:Monitoring Back Pressure;
- Flink HA 机制:Flink HA Overview;
-
状态存储层:负责存储算子的状态信息
Flink 整体架构
-
JobManager(JM)负责整个任务的协调工作,包括:调度 task、触发协调 Task 做 Checkpoint、协调容错恢复等,核心有下面三个组件:
- Dispatcher: 接收作业,拉起 JobManager 来执行作业,并在 JobMaster 挂掉之后恢复作业;
- JobMaster: 管理一个 job 的整个生命周期,会向 ResourceManager 申请 slot,并将 task 调度到对应 TM 上;
- ResourceManager:负责 slot 资源的管理和调度,Task manager 拉起之后会向 RM 注册;
-
TaskManager(TM):负责执行一个 DataFlow Graph 的各个 task 以及 data streams 的 buffer 和数据交换。
Flink 如何做到流批一体
批式计算是流式计算的特例,Everything is Streams,有界数据集(批式数据)也是一种数据流、一种特殊的数据流;
站在 Flink 的角度,Everything is Streams,无边界数据集是一种数据流,一个无边界的数据流可以按时间切段成一个个有边界的数据集,所以有界数据集(批式数据)也是一种数据流。因此,不管是有边界的数据集(批式数据)还是无边界数据集,Flink 都可以天然地支持,这是 Flink 支持流批一体的基础。并且 Flink 在流批一体上,从上面的 API 到底层的处理机制都是统一的,是真正意义上的流批一体。
Apache Flink 主要从以下几个模块来做流批一体:
- SQL 层;
- DataStream API 层统一,批和流都可以使用 DataStream API 来开发;
- Scheduler 层架构统一,支持流批场景;
- Failover Recovery 层 架构统一,支持流批场景;
- Shuffle Service 层架构统一,流批场景选择不同的 Shuffle Service;
Flink 架构优化
Flink 如何支持 OLAP 场景
Flink 做 OLAP 的优势
-
统一引擎:流处理、批处理、OLAP 统一使用 Flink 引擎;
- 降低学习成本,仅需要学习一个引擎;
- 提高开发效率,很多 SQL 是流批通用;
- 提高维护效率,可以更集中维护好一个引擎;
-
既有优势:利用 Flink 已有的很多特性,使 OLAP 使用场景更为广泛;
- 使用流处理的内存计算、Pipeline;
- 支持代码动态生成;
- 也可以支持批处理数据落盘能力;
-
相互增强:OLAP 能享有现有引擎的优势,同时也能增强引擎能力
- 无统计信息场景的优化;
- 开发更高效的算子;
- 使 Flink 同时兼备流、批、OLAP 处理的能力,成为更通用的框架。
Flink OLAP 场景的挑战
-
秒级和毫秒级的小作业;
-
作业频繁启停、资源碎片;
- Flink OLAP 计算相比流式和批式计算,最大的特点是 Flink OLAP 计算是一个面向秒级和毫秒级的小作业,作业在启动过程中会频繁申请内存、网络以及磁盘资源,导致 Flink 集群内产生大量的资源碎片;
-
Latency + 高 APS 要求;
- OLAP 最大的特点是查询作业对 Latency 和 QPS 有要求的,需要保证作业在 Latency 的前提下提供比较高的并发调度和执行能力,这就对 Flink 引擎提出了一个新的要求。
-
Flink OLAP 架构现状
-
Client:提交 SQL Query;
-
Gateway:接收 Client 提交的 SQL Query,对 SQL 进行语法解析和查询优化,生成 Flink 作业执行计划,提交给 Session 集群;
-
Session Cluster:执行作业调度及计算,并返回结果。
- JobManager 管理作业的执行,在接收到 Gateway 提交过来的作业逻辑执行计划后,将逻辑执行计划转换为物理执行计划,为每个物理计算任务分配资源,将每个计算任务分发给不同的 TaskManager 执行,同时管理作业以及每个计算任务执行状态;
- TaskManager执行具体的计算任务,采用线程模型,为每个计算任务创建计算线程,根据计算任务的上下游数据依赖关系跟上游计算任务建立/复用网络连接,向上游计算任务发送数据请求,并处理上游分发给它的数据。
-
Flink 在 OLAP 架构上的问题与设想
-
架构与功能模块:
- JobManager 与 ResourceManager 在一个进程内启动,无法对JobManager 进行水平扩展;
- Gateway 与 Flink Session Cluster 互相独立,无法进行统一管理;
-
作业管理及部署模块:
- JobManager 处理和调度作业时,负责的功能比较多,导致单作业处理时间长、并占用了过多的内存;
- TaskManager 部署计算任务时,任务初始化部分耗时验证,消耗大量 CPU;
-
资源管理及计算任务调度:
- 资源申请及资源释放流程链路过长;
- Slot 作为资源管理单元,JM 管理 slot 资源,导致 JM 无法感知到 TM 维度的资源分布,使得资源管理完全依赖于 ResourceManager;
-
其他:
- 作业心跳与 Failover 机制,并不合适 AP 这种秒级或毫秒级计算场景;
- AP 目前使用 Batch 算子进行计算,这些算子初始化比较耗时;