Flink 数据处理的流程概述
在我们处理数据的过程,无论是什么执行引擎都可以抽象为3 个总要的组件 source ,operator , sink
source 它就是我们需要处理的数据
operator 我们需要对这个数据进行的一个计算抽象(比如对这个数据进行一个加减乘除 等)
sink 我们operator 计算好的结果输出他的下游(比如 放入到db,mq 里面等)
我们接下来的分析从source 开始
首先看一下source 的结构
SourceFunction 里面也有一个内部接口 SourceContext
SourceFunction 里面有个run 方法 和一个cancel 方法,run 方法就是接受一个 SourceContext 这个对象,在run 方法里面通常实现方式,就是利用SourceContext 进行一个数据搜集,转发给operator 进行一个计算
如下所示:
public void run(SourceContext
while (isRunning && count < 1000) {
// this synchronized block ensures that state checkpointing,
// internal state updates and emission of elements are an atomic operation
synchronized (ctx.getCheckpointLock()) {
ctx.collect(count);
count++;
}
}
}
这是一个基本的用法,当然Flink 为了能够提高整体的吞吐,拓展了很多接口,比如ParalleSourceFunction 他就是一个并行的一个SourceFunction ,也就是数我们的source 可以有多个,比如当我们去消费kafka 的时候,kafka 有多少分区我们可以并行的多少这样的Source 取消费,还能保证分区的顺序性
Flink 的Source 接口抽象挺好的,就是无论你是并行还是其他的SourceFunction 他的核心实现就是通过SourceContext 的collect 方法,将数据发送到下游operator 进行一个计算,唯一不同的就是在各种子类里面他们有可能需要保存一些状态信息,比如kafka 的消费位点,这个不在本文的讨论中,下次有机会在分析
接下来我们就可以去看operator 如何处理source发送过来的数据
StreamOperator 是真个Operator 的基类,所以就定义了一些基本的 生命周期方法
setup 就是在初始化operator 的时候会调用到
open 就是在处理真正的数据时候会调用
close 就是当我们数据处理完了,会被调用
dispose 就是整个生命周期结束会被调用
其他方法不在这里介绍
StreamOperator 只是最基本的一些功能,所已我们如果根号的使用它还需对他进行一个扩展,如下
可以看到StreamOperator 实现了还是很太多,有TowInputStreamOperator OneInputStreamOperator 他们分别对应了,有两个输入 和一个输入的处理接口
processElement1 / 2 就是两条数据进行一个组合处理,其实这个可以组合成为N 个数据输入的处理
与之对应的就仅仅只有一个输入的
我们选着一个window 来进行一个讲解,因为这个目前相对于来说使用的比较多也更加容易接受其他的operator 类似
window 其实就是将数据收到过后放在本应该属于那个window (这里可以理解为容器),然后如果是 按照事件时间来处理的话,就等着水位线到来的时候进行一个计算
当我们收到数据的收 首先会调用的是processElement 方法
首先通过 windowAssigner 分配应该属于 哪一个windows,通过收到element 的时间进行一个划分
这个assigner 也有很多实现
对应到我们的使用就是一些Sliding window Tumbling window 这个划分就是按照这个数或者系统时间来进行一个划分他应该属于在那个区域
当然window 有可是需要进行一个合并比如 一个session window,前后两次数据间隔小于你的session 定义的值,他他就需要进行一个合并
当我们合并完窗口过后,我们开始讲数据放入到我们的window的state 里面
每一个数据都一个一个namespace ,最后我们的数据也是放在了state 里面
然后检查数据是否需要出发计算
如果数据需要出发计算则重state 里面获取内容,之后调用 emitWindowContents(actualWindow, contents)
emitWindowContents 就是调用我们的userFunction 的process 方法,这个userFunction 就是我们定义的数据实际的操作
真个数据的处理就是 source 发送给operator,operator 计算数据按照我们userFunction定义的处理方式进行,之后在清理state处理过的数据 当然这其中还包括一个 延迟数据,和早到的数据 以及state 的相关内容,这里没有展开讲解,本篇主要是讲一个大概流程,细节后面再进行一个分析