Apache Flink | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第3天
Apache Flink 是什么?
一. 概述
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。Flink以数据并行和流水线方式执行任意流数据程序,Flink的流水线运行时系统可以执行批处理和流处理程序。此外,Flink的运行时本身也支持迭代算法的执行。
二. 架构
2.1 Flink的分层架构:
- SDK层:Flink的SDK目前主要有三类,SQL/Table、DataStream、Python;
- 执行引擎层(Runtime层):执行引擎提供了统一的DAG,用来描述数据处理的Pipeline,不管是流还是批,都会转化为DAG图。调度层再把DAG转化成分布式环境下的Task,Task之间通过Shuffle传输数据;
- 状态存储层:负责存储算子的状态信息;
- 资源调度层:目前Flink可以支持部署在多种环境。
2.2 Flink的总体架构:
一个Flink集群,主要包含以下两个核心组件:
-
JobManager(JM):负责整个任务的协调工作,包括:调度task、触发协调Task做Checkpoint、协调容错恢复等,JObManager包含Dispatcher、JobMaster、ResourceManager三个子组件。
-
TaskManager(TM):负责执行一个DataFlowGraph的各个task以及data streams的buffer和数据交换。
三. DataFlow Model:
3.1 Flink作业示例:
流式的WordCount示例,从kafka中读取一个实时数据流,每10s统计一次单词出现次数,DataStream实现代码如下:
DataStream<String> lines = env.addSource(
new FlinkKafakaConsumer<>(...));
DataStream<Event> events = lines.map((line) ->parse(line));
DataStream<Statistics> stats = events
.keyBy(event -> event.id)
.timeWindow(TIme.seconds(10))
.apply(new MywindowAggregationFunction());
stats.addSink(new BucketingSink(path));
为了更高效地分布式执行,Flink会尽可能地将不同的operator链接(chain)在一起形成Task。
这样每个Task可以在一个线程中执行,内部叫做OperatorChain,如下图的source和map算子可以Chain在一起。
最后将上面的Task调度到具体的TaskManager中的slot中执行,一个Slot只能运行同一个task的sub Task
四. Flink的流批一体:
4.1 为什么需要流批一体:
上述架构有一些痛点:
- 人力成本比较高:流、批两套系统,相同逻辑需要开发两遍;
- 数据链路冗余:本身计算内容是一致的,由于是两套链路,相同逻辑需要运行两遍,产生一定的资源浪费;
- 数据口径不一致:两套系统、两套算子、两套UDF,通常会产生不同程度的误差,这些误差会给业务方带来非常大的困扰。