1. 微批
在批处理中,接受的数据一直在产生,首选会有一个 queue 在持续不断的收集这些持续不断产生的数据。按照时间分段处理,在将结果累加起来。
比如,在统计 wordcount 时, 一个单词 a 在1点到2点的批中出现了2次,在2到4点的批中出现了3次,那么在4点时,批处理输出的a 的频率是3,而不是 2+3=5,解决办法是将1点到2点这个时间段的统计,保留在下一个时间中,然后在下一个时间段批数据中进行累加。
可是当出现更加复杂的情况时,如数据发生了乱序,本来在2点到4点出现的单词,突然出现在了点到1点到2点,也就是数据的发生时间/次序发生的乱序。此时就会很难处理。
2. 流处理
流处理如上的场景的时,定义了2个理想条件,因此状态和时间是流式处理最本质的特点:
- 状态计算及维护:这个状态是从流式处理中处理流过的数据而得到的,也就是一个状态代表着这个处理接受到的过去的所有的数据
- 时间的维护:流计算框架需要知道当前时间,根据时间去判断数据到来与否,比如现在是3点,那么 flink 需要知道到目前为止3点之前的数据都已经到了,然后根据时间去触发计算。
Flink 的大部分知识点都是来源于上面两点:
- 状态的计算:这个状态是从流式处理中处理流过的数据而得到的,也就是一个状态代表着这个处理接受到的所有的数据,涉及到状态的计算,那么就是 flink 的状态编程,有各种的数据结构的状态,如 valueState、MapState等,这是状态的计算。
- 状态的存储形式:checkpoint 和 savepoint,提到 checkpoint 那么就扯出了 flink 的精准一次的实现逻辑,包括 checkpoint barrier 等。
- 状态的存储位置:就是 Flink 状态后端,目前支持2种状态后端,一种是基于内存的,也就是 JVM HEAP,还有一种是基于磁盘的 RockDB。
- 时间的语义:窗口的起始时间取决于3种时间语义,Event Time(元素自带)、Processing Time(当前机器时间)、Ingestion Time(事件到达 Flink Souce 时间)
- 时间的延迟处理:watermark 和时间窗口的使用
- 状态和时间计算:就是各种各样的聚合方法,reduce 和 aggregate 以及对于的各种富函数 processfunction 等。