Flink Window API


发布于 2021-01-16 / 50 阅读 / 0 评论 /
Flink支持Window,以便对窗口中的数据进行统一处理。

1.Window类型

window即窗口,就是将无限流切割为有限流的一种方式,它会将流数据分发到有限大小的桶(bucket)中进行分析。

window的类型有两种:时间窗口和计数窗口。时间窗口又分为滚动时间窗口、滑动时间窗口、会话窗口。计数窗口分为滚动计数窗口和滑动计数窗口。

1.1.滚动窗口

Tumbling window,将数据依据固定的窗口长度对数据进行切分,特点是“时间对齐,窗口长度固定,没有重叠”。如下图所示:

元素的划分遵循“左闭右开”规则,即上图中第三根虚线上的点属于window3,而不属于window2。

1.2.滑动窗口

Sliding Windows,滑动窗口是固定窗口更广义的一种形式,滑动窗口由固定的窗口长度和滑动间隔组成,窗口长度固定,可以有重叠。如下图所示:

图中,window slide表示滑动步长。每条数据最多可属于1 + ceil(window_slide / (window_size - window_slide))个窗口。

1.3.会话窗口

Session Windows,指由一系列事件组合一个指定时间长度timeout间隔组成,也就是一段时间(session gap)没有接收到新数据就会生成新的窗口。特点是“时间无对齐”。如下图所示:

图中,session gap表示会话时间最小时间间隔。

2.Window API的使用方法

主要介绍window api的使用案例。窗口的分配由相应Window类中的assignWindows函数决定,具体实现方法可查看源码。

2.1.窗口分配器

Flink中有窗口分配器,即window方法。我们可以使用window()来定义一个窗口,然后基于这个window去做一些聚合或者其他处理操作。注意window()方法必须在keyBy之后才能使用。

Flink提供了更加简单的timeWindow和countWindow方法,用于定义时间窗口和计数窗口。

Flink提供了通用的WindowAssigner:滚动窗口(tumbling window)、滑动窗口(sliding window)、会话窗口(session window)、全局窗口(global window)。

2.2.窗口函数

Window function,定义了要对窗口中收集的数据做的计算操作。可以分为两类:

(1)增量聚合函数:incremental aggregation functions,每条数据到来就进行计算,博啊吃一个简单的状态,比如ReduceFunction、AggregateFunction等。

(2)全窗口函数:full window functions,先把窗口所有数据收集起来,等到计算的时候会遍历所有数据。比如ProcessWindowFunction、WindowFunction等。

虽然对数据的处理的模式由窗口函数决定,但是输出结果还是一个窗口输出一次,每个分组有一个输出。

2.3.trigger

触发器,定义window什么时候关闭,触发计算并输出结果。

每个trigger需定义以下函数:

(1)onElement():每个元素被添加到窗口时调用

(2)onEventTime():当一个已注册的事件时间计时器启动时调用

(3)onProcessingTime():当一个已注册的处理时间计时器启动时调用

(4)onMerge():与状态性触发器相关,当使用会话窗口时,两个触发器对应的窗口合并时,合并两个触发器的状态

(5)clear():执行任何需要清除的相应窗口

trigger中的函数返回结果为TriggerResult,枚举值有:

(1)CONTINUE:什么也不做

(2)FIRE:触发计算

(3)PURGE:清除窗口中的数据

(4)FIRE_AND_PURGE:触发计算并清除窗口中的数据

2.4.其他API

有以下几种:

(1)evictor:移除器,定义移除某些数据的逻辑。

(2)allowedLateness:允许处理迟到的数据。

(3)sideOutputLateDate:将迟到的数据放入侧输出流。

(4)getSideOutput:获取侧输出流。

3.Flink时间语义

Flink中与时间相关的语义有以下三种:

(1)Event Time:事件创建的时间。

(2)Ingestion Time:数据进入Flink的时间。

(3)Processing Time:执行操作算子的本地系统时间,与机器相关。

各时间语义在流程图中的含义如下图所示:

不同的时间语义有不同的应用场景。在代码中,可以通过setStreamTimeCharacteristic方法来设置流的时间特性。默认使用EventTime,即Flink会根据数据里的时间戳来处理基于时间的算子。

4.水位线——Watermark

Watermark是一种衡量EventTime进展的机制,用来让程序自己平衡延迟和结果的正确性,可以设定延迟触发。Watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用Watermark机制结合window来实现。

数据流中的Watermark用与表示timestamp小于Watermark的数据都已到达,因此window的执行也是由Watermark触发的。

4.1.Watermark的特点

Watermark是一条特殊的数据记录,从源码中可知它扩展自StreamElement类。

Watermark必须是单调递增的,以确保任务的事件事件时钟在向前推进,而不是在后退。

Watermark与数据的时间戳有关。

4.2.Watermark的设定原则

在flink中,watermark由应用程序开发人员生成。如果watermark设置的延迟太久,收到结果的速度可能就会很慢,解决办法是在水位线到达之前输出一个近似结果。而如果watermark达到得太早,则可能收到错误结果,不过flink处理迟到数据的机制可以解决这个问题。