这是我参与「第四届青训营」笔记创作活动的第1天 、
Flink概述
Flink诞生背景
大数据(Big Data):指无法在一定时间内用常规软件工具对其进行获取、存储、管理和处理的数据集合。
特点:
- Value(价值化):整体价值高
- Volumes(海量化):数据量大
- Velocity(快速化):处理速度快
- Variety(多样化):数据源和数据种类多样
发展历史
-
Hadoop
- 分布式
- Map-Reduce
- 离线计算
-
Spark
- 批处理
- 流处理
- SQL高阶API
- 内存迭代计算
-
Flink
- 流计算
- 实时.更快
- 流批一体
- Streaming/Batch SQL
为什么要流式计算
大数据的实时性价值更大:
- 监控场景:如果能实时发现业务系统的健康状态,就能提前避免业务故障;
- 金融风控:如果实时监测出异常交易的行为,就能及时阻断风险的发生;
- 实时推荐:比如在抖音,如果可以根据用户的行为数据发掘用户的兴趣、偏好,就能向用户推荐更感兴趣的内容;
大数据实时性的需求,带来了大数据计算架构模式的变化
批式计算
- 离线计算,非实时
- 静态数据集
- 小时/天等周期性计算
流式计算
- 实时计算,快速、低延迟
- 无限流、动态、无边界
- 7*24 h持续运行
- 流批一体
Apache Flink开源生态
Resource Manager:可以部署在物理机上,也可以部署在大数据的资源调度框架上(Yarn、K8s….)
Flink ML:Flink机器学习
Flink架构
Flink分层架构
- SDK 层:Flink 的SDK目前主要有三类, SQL/Table,DataStream、Python(支持AI和ML场景)
- 执行引擎层(Runtime层):执行引擎层提供了统的DAG用来描述数据处理的Pipeline,不管是流还是批,都会转化为DAG图的编排方式,调度层再把DAG转化成分布式环境下的Task,将Task转发到不同的Worker结点去执行,Task之间通过Shuffle传输数据;
- 状态存储层:负责存储算子的状态信息;
- 资源调度层:目前Flink可以支持部署在多种环境。
Flink整体架构
一个Flink集群,主要包含以下两个核心组件:
- JobManager ( JM ) : 负责整个任务的协调工作(包括调度task、触发协调Task做Checkpoint、 协调容错恢复等)
- TaskManager ( TM ):负责执行一一个DataFlowGraph的各个task以及data streams的buffer和 数据交换。
首先Program Code(Java、SQL代码)会做一些处理,转换成DAG的一张图,Client会将这张图发送给Job Manager,Job Manager会将图转换成这张图转换为一张物理执行图,并且JM会根据物理执行图的任务调度再把不同的Task调度到Task Manager里面
Job Manager职责
- Dispatcher:接收Client发来的作业,拉起JobManager来执行作业,并在JobMaster挂掉之后恢复作业;
- JobMaster:管理一个job的整个生命周期,会向ResourceManager申请slot,并将task调度到对应TM上;
- ResourceManager:负责slot资源的管理和调度,Task manager拉起之后会向RM注册,注册成功后;
Client提交一个作业,Dispatcher拉起一个Job Master,Job Master去向Resource Manager申请slot(资源),如果用K8s或者Yarn进行资源调度,调用API去拉取一些(Task 的)资源,再通过Job Manager去部署在Task Manager上
Flink作业示例
从Kafka中读取一个实时数据流,每10s统计一次单词出现次数
env.addSource(
new FlinkKafkaConsumer<>()
);
- 创建连接并从Kafka消息队列中读取数据,可以指定Kafka地址、订阅(Topic)等信息FlinkKafkaConsumer (API) (apache.org)
- 读取到的数据基本上就是一个String(字符串)
- 随后进行map操作:对lin(每一行数据)进行parse处理,就是将包含空格的整个字符串拆开,拆成event格式
- 之后对event进行keyby操作:按照到此做分发,同样的单词的数据分发到一个地方
- 随后设计了一个10s的窗口
- 随后是指定一个聚合函数apply去执行什么计算(在WordCOunt中接收到了Key即统计频次,相同的key+1)
- 最后通过addSink去将计算结果保存下来
假设作业的sink算子的并发配置为1,其余算子并发为2 紧接着会将上面的Streaming DataFlow Graph转化Parallel Dataflow (内部叫Execution Graph) :
为了更高效地分布式执行,Flink 会尽可能地将不同的operator链接(chain)在一起形成Task。 这样每个Task可以在一个线程中执行,内部叫做OperatorChain,如”下图的source和map算子可以Chain在一起。
这里上游Source算子执行完毕后,会执行map去做paser操作,它不需要有hash、shuffle的过程,可以把数据chain在一起当成一个算子,让source[1]和map[1]在一个线程里执行(一条source读入之后,直接做map解析)避免了线程切换,序列化反序列化的一系列操作。
最后将上面的Task调度到具体的TaskManager中的slot中执行,一个Slot只能运行同-一个task的subTask
Flink的流批一体
为什么需要流批一体
- 在抖音中,实时统计一个短视频的播放量、点赞数也包括抖音直播间的实时观看人数等;(流)
- 在抖音中,按天统计创造者的一些数据信息,比如 昨天的播放量有多少、评论量多少、广告收入多少;(批)
根据数据来源,流、批可以分别有两套系统
由此可以看出,以上架构有一些痛点
1.人力成本比较高:批、流两套系统,相同逻辑需要开发两遍; 2.数据链路冗余:本身计算内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一 定的资源浪费; 3.数据口径不一致:两套系统、两套算子、两套UDF,通常会产生不同程度的误差,这些误差 会给业务方带来非常大的困扰。
Flink如何做到流批一体
1.批式计算是流式计算的特例,Everything is Streams ,有界数据集(批式数据)也是一-种数据流、种特殊的数据流; 因此,理论上我们是可以用一套引|擎架构来解决上述两种场景,只不过需要对不同场景支持相应的扩展性、并允许做不同的优化策略。
站在Flink 的角度,Everything is Streams,无边界数据集是一种数据流,一个无边界的数据流可以按 时间切段成一个个有边界的数据集 ,所以有界数据集(批式数据)也是一种数据流。
因此,不管是有边界的数据集(批式数据)还是无边界数据集,Flink 都可以天然地支持,这是Flink 支持 流批一体的基础。并且Flink 在流批一体上,从上面的API到底层的处理机制都是统一的,是真正意义,上 的流批一体。
Apache Flink 主要从以下几个模块来做流批一体:
-
SQL层;
-
DataStream API层统一,批和流都可以使用DataStream API来开发;
-
Scheduler 层架构统一- ,支持流批场景;
主要负责将作业的DAG转化为分布式环境中可以执行的Task
Flink支持以下两种调度模式
模式 特点 场景 EAGER 申请一个作业所需要的全部资源,然后同时调度这个作业的全部Task ,所有的Task之间采取Pipeline的方式进行通信 Stream作用场景 LAZY 先调度上游,等待上游产生数据或结束后再调度 下游,类似Spark的Stage执行模式。 Batch作用场景 -
Failover Recovery层架构统- - ,支持流批场景;
-
Shuffle Service层架构统- ,流批场景选择不同的Shuffle Service ;
Flink架构优化
流/批/OLAP业务场景概述
在实际生产环境中,针对不同的应用场景我们对数据处理的要求是不同的 : 1.有些场景下,只需离线处理数据,对实时性要求不高,但要求系统吞吐率高,典型的应用是 搜索弓|擎构建索引; 2.有些场景下,需对数据进行实时分析,要求每条数据处理延迟尽可能低,典型的应用是广告 推荐、金融风控场景。
应用场景:
1.在抖音中,实时统计一个短视频的播放量、点赞数也包括抖音直播间的实时观看人数等; 2.在抖音中,按天统计创造者的一些数据信息,比如昨天的播放量有多少、评论量多少、广告收入多少 3.在抖音的一些推广活动中,运营同学需要对一-些实时产出的结果数据做一些实时多维分析 ,来帮助后 面活动的决策。
OLAP架构
- Client :提交SQL Query ; Gateway
- 接收Client提交的SQL Query,对SQL进行语法解析和查询优化,生成Flink作业执行计划,提交给 Session集群;
- Session Cluster 执行作业调度及计算,并返回结果。
作业管理及部署模块:
- JobManager 处理和调度作业时,负责的功能比较多, 导致单作业处理时间长并占用了过多的内存;
- TaskManager部署计算任务时,任务初始化部分耗时严重,消耗大量CPU。
其他: 1.作业心跳与Failover机制,并不合适AP这种秒级或毫秒级计算场景; 2.AP目前使用Batch算子进行计算,这些算子初始化比较耗时;。
最终演进结果: