彻底搞清Flink中的Window

flink-window

窗口

在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理。当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的网页。在这种情况下,我们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。

Flink 认为 Batch 是 Streaming 的一个特例,所以 Flink 底层引擎是一个流式引擎,在上面实现了流处理和批处理。而窗口(window)就是从 Streaming 到 Batch 的一个桥梁。

一个Window代表有限对象的集合。一个窗口有一个最大的时间戳,该时间戳意味着在其代表的某时间点——所有应该进入这个窗口的元素都已经到达

Window就是用来对一个无限的流设置一个有限的集合,在有界的数据集上进行操作的一种机制。window又可以分为基于时间(Time-based)的window以及基于数量(Count-based)的window。

Flink DataStream API提供了Time和Count的window,同时增加了基于Session的window。同时,由于某些特殊的需要,DataStream API也提供了定制化的window操作,供用户自定义window。

窗口的组成 窗口分配器

assignWindows将某个带有时间戳timestamp的元素element分配给一个或多个窗口,并返回窗口集合

getDefaultTrigger 返回跟WindowAssigner关联的默认触发器

getWindowSerializer返回WindowAssigner分配的窗口的序列化器

窗口分配器定义如何将数据元分配给窗口。这是通过WindowAssigner 在window(...)(对于被Keys化流)或windowAll()(对于非被Keys化流)调用中指定您的选择来完成的。

WindowAssigner负责将每个传入数据元分配给一个或多个窗口。Flink带有预定义的窗口分配器,用于最常见的用例
即翻滚窗口, 滑动窗口,会话窗口和全局窗口。

您还可以通过扩展WindowAssigner类来实现自定义窗口分配器。

所有内置窗口分配器(全局窗口除外)都根据时间为窗口分配数据元,这可以是处理时间或事件时间。

State

状态,用来存储窗口内的元素,如果有 AggregateFunction,则存储的是增量聚合的中间结果。

窗口函数

选择合适的计算函数,减少开发代码量提高系统性能

增量聚合函数(窗口只维护状态)

ReduceFunction

AggregateFunction

FoldFunction

全量聚合函数(窗口维护窗口内的数据)

ProcessWindowFunction

全量计算

支持功能更加灵活

支持状态操作

触发器

image-20210202200655485

EventTimeTrigger基于事件时间的触发器,对应onEventTime

ProcessingTimeTrigger
基于当前系统时间的触发器,对应onProcessingTime
ProcessingTime 有最好的性能和最低的延迟。但在分布式计算环境中ProcessingTime具有不确定性,相同数据流多次运行有可能产生不同的计算结果。

ContinuousEventTimeTrigger

ContinuousProcessingTimeTrigger

CountTrigger

Trigger确定何时窗口函数准备好处理窗口(由窗口分配器形成)。每个都有默认值。
如果默认触发器不符合您的需要,您可以使用指定自定义触发器。WindowAssignerTriggertrigger(...)

触发器界面有五种方法可以Trigger对不同的事件做出反应:

onElement()为添加到窗口的每个数据元调用该方法。

onEventTime()在注册的事件时间计时器触发时调用该方法。

onProcessingTime()在注册的处理时间计时器触发时调用该方法。

该onMerge()方法与状态触发器相关,并且当它们的相应窗口合并时合并两个触发器的状态,例如当使用会话窗口时。

最后,该clear()方法在移除相应窗口时执行所需的任何动作。

默认触发器

默认触发器GlobalWindow是NeverTrigger从不触发的。因此,在使用时必须定义自定义触发器GlobalWindow。

通过使用trigger()您指定触发器会覆盖a的默认触发器WindowAssigner。例如,如果指定a CountTrigger,TumblingEventTimeWindows则不再根据时间进度获取窗口,
而是仅按计数。现在,如果你想根据时间和数量做出反应,你必须编写自己的自定义触发器。

event-time窗口分配器都有一个EventTimeTrigger作为默认触发器。该触发器在watermark通过窗口末尾时出发。

触发器分类 CountTrigger

一旦窗口中的数据元数量超过给定限制,就会触发。所以其触发机制实现在onElement中

ProcessingTimeTrigger

基于处理时间的触发。

EventTimeTrigger

根据 watermarks 度量的事件时间进度进行触发。

PurgingTrigger

另一个触发器作为参数作为参数并将其转换为清除触发器。

其作用是在 Trigger 触发窗口计算之后将窗口的 State 中的数据清除。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwzpd.html