Flink中自定义窗口算子

虽然Flink提供的窗口算子已经够用了,但是当一些特殊的高级的流式应用出现的时候,会发现可能需要更为复杂的窗口逻辑.

DataStream就为此提供了自定义窗口的接口及算法,可以自定义分配器 触发器 移除器

来共同的进行协同工作,从而实现自定义一个窗口

一个窗口的具体工作过程为:

首先一个元素进入窗口之后会被移交给分配器,其决定了元素该放在哪个窗口中

然后窗口配置的是聚合函数的话,那么会立刻执行聚合,结果为窗口内容存储,如果没有配置聚合函数,那么先将事件放在ListState上

然后加入窗口后触发窗口的触发器,触发器来定义窗口是否准备好计算

触发器判断可以完成窗口后,就进行下一步,即如果是聚合参数就直接发出去,如果是全量窗口函数,就将ListState传递给全量窗口函数

图片

图片

最后是移除器,这是一个可选的组件,允许你在调用前或者之后进行引入,从而删除已经收集的元素,需要注意要在没有指定增量聚合函数的时候使用.

增提的逻辑可以如下

图片

为了保证窗口的API简洁,那么没有定义触发器的WindowAssigner都会提供一个默认的触发器

窗口内部维护了一些状态

窗口会在WindowAssigner首次分配元素的时候创建,窗口内部首先包含了窗口内容,也就是窗口内部的元素

触发器计时器,在触发器中注册个计时器,方便回来回调

触发器的自定义状态, 定义每个窗口内都可以有自己的状态

窗口需要删除的时候,自定义的触发器状态和触发器注册的计时器不会被清除,这些是需要手动在Trigger.clear()来进行清除状态

那么接下来我们来依次看对应的组件

1.     窗口分配器

用于确定元素分配到哪个窗口中,接口结构为

图片

需要注意在其中生成一个触发器

2.     触发器,来决定何时计算,何时发出结果,触发条件可以是时间,可以试试特定数据条件,比如某个特定事件,而且前文说过,内部可以有状态,某种状态上等价于处理函数.

而且每次调用都有一个TriggerResult,决定窗口接下来的行为,可以为 Continue 什么都不做 FIRE 发出结果 PURGE 清除窗口状态,此时会调用ProcessWindowFunction,clear(),FIRE_AND_PURGE 先进行窗口,然后删除

接口定义如下:

图片

触发器中需要注意,需要在窗口删除的时候清理自身的窗口状态,不然会越来越多

还有就是如果希望窗口可以被合并,需要在canMerge中声明支持合并

我们接下来给出一个触发器的示例

图片

上面的触发器在第一次事件到达时注册了一个触发器,此后每次触发时候就再次触发一次.

3.     移除器

最后是自定义窗口机制的可选组件,在执行计算之后或者之前删除元素

图片

发表评论

邮箱地址不会被公开。 必填项已用*标注