这是我参与「第四届青训营 」笔记创作活动的第2天
流/批/OLAP 一体的 Flink 引擎介绍
课程目录
- Flink概述
- Flink整体架构
- Flink架构优化
- 精选案例讲解
1.Flink概述
1.1 Apache Fink诞生背景
1.1.1什么是大数据
- 海量化(Volumes)
- 多样化(Variety)
- 快速化(Velocity)
- 价值化(Value
1.1.2大数据计算架构发展历史
1.1.3为什么需要流式计算
大数据实时性需求,带来大数据计算架构模式的变化如:
- 监控场景:提前避免业务故障
- 金融风控: 实时监测异常交易行为,减少金融风险
- 推荐系统:抖音头条实时推荐
而批式计算不满足实时性的需求
1.2为什么Apache Flink会脱颖而出
1.2.1流式计算引擎发展历程
1.2.2流式计算引擎对比
流式计算框架对比:
1.2.3 Why Flink
1.3Apache Flink 开原生态
2.Flink整体架构
2.1Flink分层架构
- SDK层:Flink的SDK目前主要有三类,SQL/Table(方便SQL查询)、 DataStream、 Python(用于机器学习)
- 执行引擎层(Runtime 层):执行引擎层提供了统一的 DAG,用来描述数据处理的 Pipeline,不管是流还是批,都会转化为 DAG 图,调度层再把 DAG 转化成分布式环境下的 Task,Task 之间通过 Shuffle 传输数据
- 状态存储层:负责存储算子的状态信息
- 资源调度层:目前 Flink 支持部署在多种环境。
2.2Flink整体架构
一个Flink集群主要包含以下两个核心组件:
JobManager(JM):负责整个任务的协调工作,包括:调度 Task 、触发协调 Task 做Checkpoint、协调容错恢复等
主要职责:
(1)Dispatcher:接收作业,拉起 JobManager 来执行作业,并在 JobMaster 挂掉之后恢复作业;
(2)JobMaster:管理一个 Job 的整个生命周期,会向 ResourceManager 申请 Slot ,并将 Task 调度到对应 TM 上;
(3)ResourceManager:负责 Slot 资源的管理与调度, TaskManager 拉起之后会向 RM 注册。
TaskManager(TM): 负责执行一个 DataFlow Group 的各个 task 以及 Data Streams 的 buffer 和数据交换。
2.3Flink作业示例
流式的WordCount示例,从Kafka中读取一个实时数据流,每10s统计一次单词出现次数,DataStream实现代码如下C++:
业务逻辑转换为一个Streaming DataFlow Graph
2.4Flink如何做到流批一体
2.4.1为什么需要流批一体
如图在原有架构下流批分离,数据从数据源分别流向实时数仓(Flink)和离线数仓(Spark/Hive)存在一些痛点:
(1)人力成本较高:批、流两套系统,相同逻辑需要开发两遍;
(2)数据链路冗余:本身设计内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一定的资源浪费;
(3)数据口径不一致:两套系统、两套算子、两套 UDF ,通常会产生不同程度的误差,这些误差会给业务方带来非常大的困扰
2.4.2流批一体的挑战
流批业务场景的特点如下表:
| 流式计算 | 批式计算 |
|---|---|
| 实时计算 | 离线计算 |
| 延迟在秒级以内 | 处理时间在分钟到小时级别甚至天级别 |
| 0~1 s | 10 s ~ 1 h+ |
| 广告推荐、金融风控 | 搜索引擎构建索引、批式数据分析 |
批示计算相比于流式计算核心的区别如下表:
| 维度 | 流式计算 | 批式计算 |
|---|---|---|
| 数据流 | 无线数据 | 有限数据 |
| 时延 | 低延迟、业务会感知运行中的状态 | 实时性要求不高,只关注最终结果产出 |
2.4.3Flink如何做到流批一体
Everything is streams
- 批式计算是流式计算的特例,只一种特殊的数据流
- 一个无边界的数据流(流式计算),可以按照时间,切成一个个有边界的数据集(批式计算),因此不管是有边界数据集(批式数据)还是无边界数据集, Flink 都可以天然支持,这是 Flink 支持流批一体的基础。并且 Flink 在流批一体上,从上层 API 到底层的处理机制都是统一的,是真正意义上的流批一体。
Apache Flink 主要从以下几个模块来做到流批一体
1.SQL层
2.DataStream API 层统一,批和流都可以使用 DataStream API 来开发
3.Scheduler 层架构统一,支持流批场景
4.Failover Recovery 层架构统一,支持流批场景
5.Shuffle Service 层架构统一,流批场景选择不同的 Shuffle Service
2.4.4流批一体的Scheduler层
Scheduler主要作用:将作业的DAG转化为在分布式环境中可以运行的Task
在1.12 之前的Flink中,Flink支持以下2种调度模式
EAGER 模式:如图12个Task会被一起调度,需要足够的资源
LAZY 模式:如图最小化调度一个Task即可,集群有一个slot资源可以运行
由Pipeline的数据交换方式连接的Task构成为一个Pipeline Region
本质上,不管是流作业还是批作业,都是按照Pipeline Region粒度来申请资源和调度任务
如图: pipleline region 的性能和使用的资源,都处于EAGER和LAZY模式之间
Blocking 和pipleline模式的区别
Blocking: 上层数据 先传入一个硬盘,再进入下一层
比如A1执行完释放资源 存入硬盘B1再执行 类似批处理
Pipeliend:上层数据 直接进入下一层
比如A1执行完释放资源 直接存入内存 B1直接接受执行 类似流处理
2.4.5流批一体的Shuffle Service层
- Shuffle:在分布式计算中,用来连接上下游数据交互的过程叫做 Shuffle。
- 实际上,分布式计算中所有涉及到上下游衔接的过程,都可以理解为 Shuffle。
不同计算框架的的Shuffle有不同的实现方式
流和批Shuffle差异
- Flink 对于流和批提供两种类型 Shuffle,虽然 Streaming 和 Batch Shuffle 在具体的策略上存在一定的差异,但本质上都是为了对数据进行 Re-Partition ,因此不同的 Shuffle 之间是存在一定共性的。
- 所以 Flink 的目标是提供一套统一的 Shuffle 架构,既可以满足不同 Shuffle 在策略上的定制,同时还能避免在共性需求上进行重复开发。
不同场景的 Shuffle
2.4.6Flink流批一体总结
经过相应的改造和优化之后,Flink在架构设计上,针对DataStream层、调度层、Shuffle Service层,均完成了对流批的支持。至此,业务已经可以非常方便地使用Flink解决流和批场景的问题了。
3.Flink架构优化
3.1流/批/OLAP业务场景概述
在实际生产环境中针对不同应用场景,我们对数据处理的要求是不同的(如实时性、吞吐率)
例:
1.在抖音中,实时统计一个短视频的播放量,点赞数,也包括抖音直播间的实时观看人数等
2.在抖音中,按天统计创造者的一些数据信息,比如昨天的播放量有多少,评论量多少,广告收入多少;
3.在抖音的一些推广活动中,运营同学需要对一些实时产出的结果数据做一些实时多维分析,来帮助后面活动的决策。
三种业务场景的特点比对如下表:
三种业务场景的解决方案的要求及带来的挑战是:
3.2三种业务场景为什么可以用一套引擎来解决
通过前述对比分析,可以发现:
(1)批式计算是流式计算的特例, Everything is Streams ,有界数据集(批式数据)也是一种数据流、一种特殊的数据流;
(2)而 OLAP 计算是一种特殊的批式计算,它对并发性和实时性要求更高,其他情况与普通批式作业没有特别大区别。
因此,理论上我们是可以用一套引擎架构来解决上述三种场景,只不过需要对不同场景支持相应的扩展性、并运行做不同的优化策略。
Apache Flink从流式计算出发,需要想支持Batch和OLAP场景,就需要解决下面的问题:
3.3Flink如何支持OLAP场景
Flink的OLAP 优化之路
- Flink做OLAP的优势
- Flink OLAP场景的挑战
- Flink OLAP架构现状
3.3.1 Flink做OLAP的优势
3.3.2 Flink OLAP场景的挑战
- 秒级和毫秒级的小作业
- 作业频繁启停,资源碎片
- Latency + QPS的要求
3.3.3 Flink OLAP架构现状
- Client:提交 SQL Query;
- Gateway:接收 Client 提交的 SQLQuery,对 SQL 进行语法解析和查询优化,生成 Flink 作业执行计划,提交给 Session 集群;
- Session Cluster:执行作业调度及计算,并返回结果。
3.3.4 Flink OLAP架构问题与设想
-
架构与功能模块:
- JobManager 与 ResourceManager 在一个进程内启动,无法对 JobManager 进行水平扩展;
- Gateway 与 Flink Session Cluster 互相独立,无法进行统一管理。
-
作业管理及部署模块:
- JobManager 处理和调度作业时,负责的功能比较多,导致单作业处理时间长、并占用了过多的内存;
- TaskManager 部署计算任务时,任务初始化部分耗时严重,消耗大量CPU。
-
资源管理及计算任务调度:
- 资源申请及资源释放流程链路过长;
- Slot 作为资源管理单元,JM 管理 slot 资源,导致 JM 无法感知到 TM 维度的资源分布,使得资源管理完全依赖于 ResourceManager。
-
其他:
- 作业心跳与 Failover 机制,并不合适 AP 这种秒级或毫秒级计算场景;
- AP 目前使用 Batch 算子进行计算,这些算子初始化比较耗时。
3.3.5 Apache Flink 最终的演化结果
4.Flink的使用案例
4.1 电商流批一体实践
抖音电商原有的离线和实时数仓架构如图:
- 目前电商业务数据分为离线数仓和实时数仓建设,离线和实时数据源,计算引擎和业务代码没有统一,在开发相同需求的时候经常需要离线和实时对齐口径,同时,由于需要维护两套计算路径,对运维也带来压力。
- 从数据源,业务逻辑,计算引擎完成统一,提高开发和运维效率。
Flink社区现状:
演进目标
4.2 Flink OLAP 场景实践
Flink的OLAP在字节内部的场景主要是HTAP场景。
原本的链路
新的链路(走HTAP之后),Flink直接提供数据查询与分析的能力
5.个人思考
对Flink有了更深的了解,知道了他的发展历程与分层架构、整体架构,知道了一个Flink作业如何调度运行,对流批的特点有了更深刻的体悟,并且知道了Flink如何做到流批一体化。最后对于不同的业务场景了解了流、批、OLAP对数据处理的优缺点和对于Flink如何支持OLAP有了一定的构思。