这是我参与「第四届青训营 」笔记创作活动的的第2天
今天是大数据专场基础班的第二次课,主要内容是介绍Flink的相关知识,主要分为下面四个板块。
一、 Flink概述
1. Apache Flink 的诞生背景
1.1 什么是大数据
- 大数据(Big Data): 指无法在一定时间内用常规软件工具对其进行获取、存储、管理和处理的数据集合
- 价值化(Value)
- 海量化(Volumes)
- 多样化(Variety)
- 快速化(Velocity)
1.2 大数据计算架构发展历史
1.3 为什么需要流式计算
- 大数据实时性的需求,带来了大数据计算架构模式的变化
2. 为什么Apache Flink会脱颖而出
2.1 流式计算引擎发展历程
- 大数据如果从Google对外发布MapReduce论文算起,已经前后跨越将近二十年,业内常用的计算框架演化历史(红框是流式计算框架)
2.2 流式计算引擎对比
- 流式计算框架对比:
2.3 Why Flink
3. Apache Flink开源生态
- Flink社区的开源生态
二、 Flink整体架构
1. Flink分层架构
- SDK层: Flink 的SDK目前主要有三类,SQL/Table、DataStream、Python
- 执行引擎层(Runtime层): 执行引擎层提供了统一的DAG,用来描述数据处理的Pipeline,不管是流还是批,都会转化为DAG图,调度层再把 DAG转化成分布式环境下的Task,Task 之间通过Shuffle传输数据
- 状态存储层: 负责存储算子的状态信息
- 资源调度层: 目前Flink可以支持部署在多种环境
2. Flink总体架构
- 一个Flink集群,主要包含以下两个核心组件:
- JobManager (JM): 负责整个任务的协调工作,包括:调度task、触发协调Task做 Checkpoint、协调容错恢复等
- TaskManager (TM): 负责执行一个DataFlowGraph的各个task以及data streams的 buffer和数据交换
3. Flink 作业示例
流式的WordCount示例,从kafka中读取一个实时数据流,每10s统计一次单词出现次数,DataStream实现代码如下:
4. Flink 如何做到流批一体
4.1 为什么需要流批一体
- 人力成本比较高: 批、流两套系统,相同逻辑需要开发两遍
- 数据链路冗余: 本身计算内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一定的资源浪费
- 数据口径不一致: 两套系统、两套算子、两套UDF,通常会产生不同程度的误差,这些误差会给业务方带来非常大的困扰
4.2 流批一体的挑战
- 流和批业务场景的特点如下表:
- 批式计算相比于流式计算核心的区别如下表:
4.3 Flink如何做到流批一体
- SQL层
- DataStream API层统一,批和流都可以使用DataStream API来开发
- Scheduler层架构统一,支持流批场景
- Failover Recovery层架构统一,支持流批场景
- Shuffle Service层架构统一,流批场景选择不同的 Shuffle Service
4.4 流批一体的 Scheduler层
scheduler主要负责将作业的DAG转化为在分布式环境中可以执行的 Task
Flink支持以下两种调度模式:
- EAGER 模式
- 16个task会一起调度,集群需要有足够的资源
- LAZY模式
- 最小调度一个task 即可,集群有1个slot资源可以运行
4.5 流批一体的 Shuffle Service层
-
Shuffle: 在分布式计算中,用来连接上下游数据交互的过程叫做 Shuffle
-
针对不同的分布式计算框架,Shuffle通常有几种不同的实现:
- 基于文件的Pull Based Shuffle,比如Spark或MR,它的特点是具有较高的容错性,适合较大规模的批处理作业,由于是基于文件的,它的容错性和稳定性会更好一些
- 基于Pipeline的Push Based Shuffle,比如Flink、Storm、Presto等,它的特点是低延迟和高性能,但是因为shufle数据没有存储下来,如果是batch任务的话,就需要进行重跑恢复
-
流和批 Shuffle之间的差异:
- Shuffle数据的生命周期: 流作业的 Shuffle 数据与Task是绑定的,而批作业的Shuffle数据与Task是解耦的
- Shuffile数据存储介质: 流作业的生命周期比较短、而且流作业为了实时性,Shuffle通常存储在内存中,批作业因为数据量比较大以及容错的需求,一般会存储在磁盘里
- Shuffle 的部署方式: 流作业 Shuffle服务和计算节点部署在一起,可以减少网络开销,从而减少latency,而批作业则不同
-
在Streaming和OLAP场景
- 为了性能的需要,通常会使用基于Pipeline的Shuffle模式
-
在Batch场景
- 一般会选取Blocking的 Shuffle模式
-
对于Shuffle Service,Flink开源社区已经支持:
- Netty Shuffle Service: 既支持pipeline 又支持blocking,Flink默认的shuffle Service策略
- Remote Shuffle Service: 既支持pipeline 又支持blocking,不过对于pipeline模式,走remote反而会性能下降,主要是有用在 batch的 blocking场景,字节内部是基于CSS来实现的RSS
小结:
- 经过相应的改造和优化之后,Flink在架构设计上,针对 DataStream层、调度层、ShuffleService层,均完成了对流和批的支持
三、 Flink架构优化
1. 流/批/OLAP业务场景概述
- 三种业务场景的的特点比对如下表:
- 三种业务场景的解决方案的要求及带来的挑战是:
2. 为什么三种场景可以用一套引擎来解决
- 批式计算是流式计算的特例,Everything is Streams,有界数据集(批式数据)也是一种数据流、-种特殊的数据流
- 而OLAP计算是一种特殊的批式计算,它对并发和实时性要求更高,其他情况与普通批式作业没有特别大区别
3. Flink 如何支持OLAP场景
3.1 Flink做OLAP的优势
3.2 Flink OLAP场景的挑战
3.3 Flink OLAP架构现状
- Client: 提交SQL Query
- Gateway
- 接收Client提交的SQL Query,对SQL进行语法解析和查询优化,生成 Flink 作业执行计划,提交给Session集群
- session Cluster
- 执行作业调度及计算,并返回结果
3.4 Flink在OLAP架构的问题与设想
-
架构与功能模块:
- JobManager与ResourceManager在一个进程内启动,无法对JobManager进行水平扩展
- Gateway Flink Session Cluster 互相独立,无法进行统一管理
-
作业管理及部署模块:
- JobManager处理和调度作业时,负责的功能比较多,导致单作业处理时间长、并占用了过多的内存
- TaskManager部署计算任务时,任务初始化部分耗时严重,消耗大量CPU
-
资源管理及计算任务调度:
- 资源申请及资源释放流程链路过长
- Slot作为资源管理单元,JM管理slot资源,导致JM无法感知到TM维度的资源分布,使得资源管理完全依赖于ResourceManager
-
其他
- 作业心跳与Failover机制,并不合适AP这种秒级或毫秒级计算场景
- AP目前使用Batch算子进行计算,这些算子初始化比较耗时
四、 精选案例讲解
1. 电商流批一体实践
- 抖音电商业务原有的离线和实时数仓架构如下图:
- Flink社区的现状
- 演进目标
- 目前电商业务数据分为离线数仓和实时数仓建设,离线和实时数据源,计算引擎和业务代码没有统一,在开发相同需求的时候经常需要离线和实时对齐口径,同时,由于需要维护两套计算路径,对运维也带来压力
- 从数据源,业务逻辑,计算引擎完成统一,提高开发和运维效率
2. Flink OLAP场景实践
- Flink的OLAP在字节内部的场景主要是HTAP场景
五、课程总结
这次课老师向我们介绍了什么是Flink,Flink的整体架构以及相关的核心概念,Flink的架构优化,最后用一些具体的实践案例来帮助我们理解Flink,让我对于Flink有了更深一步的认识
本次学习让我意识到预习的重要性,上第一次课时因为不是很适应,直接去听课,发现自己什么都听不懂。这次课之前,我浏览了学员手册,同时也阅读了部分学员手册里推荐的文章,虽然有些地方还是听不太懂,但相较于上一次课有了很大进步,希望后面能够坚持课前预习,每天都比昨天有进步!
引用参考
内容主要参考了王蒙老师在「流/批/OLAP 一体的 Flink 引擎介绍」课程里所教授的内容,图片来自于老师的PPT,链接如下: 流_批_OLAP 一体的 Flink 引擎 - 王蒙 - ppt.pptx - 飞书文档 (feishu.cn)