在实际的工作中慢慢摸索和使用Flink也有将近一年的时间了,这段时间打算好好总结和整理一下,有兴趣想要了解Flink流处理技术的,看我的这个博客合集就可以了。如果有什么问题可以多多讨论交流。以下进入正文。
- 1. Flink支持的时间语义
- 2. Watermark机制
- 2.1 背景
- 2.2 作用
- 2.3 种类
- 3.生成时间戳和水位线
- 3.1 方式一:在Source算子中生成
- 3.2 assignTimestampsAndWatermarks
- 4.Watermark分类
- 4.1 Periodic Watermark
- 4.2 Puncuated Watermark
- 4.3 内置Timestamp Assigner和Watermark Generator
- 5. 延迟数据的处理
- 5.1 默认方式:丢弃
- 5.2 允许延迟更新
- 5.3 侧输出
Flink支持三种时间语义:事件时间,吸入时间和处理时间。三个时间的概念还是比较简单的,不再赘述。
在源代码中表示如下:
@PublicEvolving
public enum TimeCharacteristic {
ProcessingTime,
IngestionTime,
EventTime
}
设置时间语义的方法:
final StreamExecutionEnvironment env=StreamExecutionEnvironment.getExecutionEnvironment(); env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
需要注意的是:一般情况下,如果使用的是EventTime语义,则需要在Source算子之后明确指定Timestamp Assigner 和 Watermark Generator。
2. Watermark机制 2.1 背景在实时分布式系统中,受到网络阻塞等影响,会造成out-of-order data或者late data,对于这部分数据,出于实时性的需要,不可能一直等下去,必须要有个机制保证在某个时间点之后就该触发窗口中数据的计算了。
2.2 作用(1)衡量事件时间的进展情况,表示在当前Watermark之前的数据都已经到齐了。
(2)用于触发基于事件时间的窗口的计算
(3)计算公式:当前系统观察到的最大事件时间 - 最大延迟处理时间,且为单调递增
(1)有序流的水位线:
(2)乱序流的水位线:
(3)并行流中的水位线:
此处需要记住一点即可:一个算子的多个并行实例会进行水位线的对齐,且会取所有并行实例中最小的。
大前提:必须是事件时间语义下。
在该语义下,Flink程序自身需要知道每个进来的event的timestamp是什么,以及该如何分配Watermark。
自定义Source算子实现SourceFunction或者RichParallelSourceFunction(一般不常用):
在assignTimestampsAndWatermarks方法内指定timestamp assigner 和 watermark generator。
或者:
间断性,非周期性的生成。
(1)AscendingTimestampExtractor
(2)BoundedOutOfOrdernessTimestampExtractor
允许固定延迟
对于晚于watermark,且超过了允许迟到的时间(如果设置了的话)的数据,Flink默认会丢弃该数据不做计算。
5.2 允许延迟更新allowedLateness()方法:需要考虑数据结果的幂等性!
可以获取到迟到的数据,另行处理,保证数据不会丢失。



