0


Flink 窗口最全汇总

一、概念

    将要计算的数据限制一个范围,统计一个范围内的数据。将无界的数据切割成有届的数据

二、分类

1)按照驱动类型分

(1):时间类型窗口(Time Window)

以时间点来定义窗口的开始(start time)和结束(end time),截取出来的就是某一时间段的数据

(2):计数窗口(Count Window)

基于元素的个数来截取数据,到达固定数据就触发计算并关闭窗口

2)按窗口分配数据的规则分类

    可以划分为四类:滚动窗口、滑动窗口、会话窗口和全局窗口

(1):滚动窗口

    有固定的大小,是对数据"均匀分片"。**窗口之间没有重叠,也不会有间隔。**每个数据都会被分配到一个窗口,而且只属于一个窗口。既可以基于时间,又可以基于个数。(滑动步长等于窗口大小,可以理解成是一种特殊的滑动窗口)

(2):滑动窗口

    窗口大小是固定的,但是窗口之间并不是首尾相接的,而是可以"错开"一定的位置。定义滑动窗口要有两个参数:窗口大小和滑动步长。既可以基于时间,又可以基于个数。

(3):会话窗口

    基于"会话"对数据分组。只能基于时间来定义。最重要的参数就是**会话的超时时间,会话窗口的长度不固定,起始时间和结束时间也不确定**

** (4):全局窗口**

** **会把相同key的所有数据都分配到一个窗口中。这种窗口没有结束的时候,默认是不会触发计算的。需要自己定义触发器

三、窗口 API

1) 按键分区(Keyed)和非按键分区(Non-Keyed)

    按键分区的数据流KeyedStream,没有按键分区的数据流DataStream,要观察是否有keyby操作

    (1) 按键分区 keyed window

经过keyBy划分后,数据会被分成多条逻辑流,就是KeyedStream。基于KeyedStream进行窗口操作时,窗口计算会在多个并行子任务上同时执行。相同key的数据被发往同一个并行子任务。代码实现上,需要先对DataStream调用.keyBy()按键分区,然后再调用.window()定义窗口

    (2)非按键分区

如果没有进行keyby,那么原始的DataStream就不会分成多条逻辑流,这时候的窗口逻辑只能在一个task上执行,相当于并行度变成了1。代码中直接基于DataStream调用.windowAll()定义窗

2) 代码中窗口API的调用

窗口操作主要有两个部分:窗口分配器(Window Assigners)和窗口函数(Window Functions)。

四、窗口分配器

1)作用

    定义数据应该被“分配”到哪个窗口。可以说,窗口分配器其实就是在指定窗口的类型

2)方法

    通用的定义方式为.window()调用,穿入一个WindowAssigner作为参数,返回一个WindowedStream。如果时非按键分区的,直接调用WindowAll()方法,同样传入一个WindowAssigner,返回AllWindowedStream

3)实现

3.1 时间窗口

3.1.1 滚动处理时间窗口
    窗口分配器由TumblingProcessingTimeWindows提供,调用他的静态方法.of(),传入一个Time类型的参数size,表示滚动窗口的大小

3.1.2 滑动处理时间窗口
    窗口分配器由SlidingProcessingTimeWindows提供,调用他的静态方法.of(),传入两个Time类型的参数,size和slide,也就是窗口的大小和滑动的步长

3.1.3 处理时间会话窗口
    窗口分配器由ProcessingTimeSessionWindow提供,需要调用他的静态方法.withGap,或者.withDynamicGap()。需要传入一个Time类型的参数size,表示会话的超时时间

3.1.4 滚动事件时间窗口
     窗口分配器由类TumblingEventTimeWindows提供,和滚动处理时间窗口完全一致
3.1.5 滑动事件事件窗口
    窗口分配器由SlidingEventTimeWindows提供,用法和滑动处理时间完全一致
3.1.6 事件时间会话窗口
    窗口分配器由类EventTimeSessionWindows提供,用法和处理时间会话窗口完全一致

3.2 计数窗口

            3.2.1 滚动计数窗口

    直接调用.countWindow,传入一个长整型的参数size,表示窗口的大小

            3.2.2 滑动计数窗口

    直接调用.countWindow,传入两个参数,表示窗口大小和步长

            3.3.3 全局窗口

    是计数窗口的底层实现,一般需要在自定义窗口时使用。他的定义是直接调用window,窗口分配器由GlobalWindows提供

五、 窗口函数

1)增量聚合

    来一条计算一条,但是并不会立即输出,当窗口触发才会输出

①:reduce

特点 1、相同key的第一条数据来的时候,不会调用reduce方法
2、来一条数据就会计算一次,但是不会输出
3、 窗口触发的时候,才会输出窗口的最终计算结果

②:aggregate

增量聚合是有三中类型的,输入类型,累加器(中间结果的类型),输出类型。aggregate可以定义三种类型,而reduce的这三种类型都为相同的,不够灵活

2)全窗口函数

    数据来了不计算,存起来,窗口触发的时候,计算并输出结果。另外,全窗口函数提供了上下文,可以拿到比如窗口的开始时间、结束时间等信息。老版本用apply方法,新版本使用process方法,new ProcessWindowFunction<输入类型,输出类型,key类型,窗口类型>

3) 增量+全窗口

优点:既实现了增量来一条计算一条,又实现了可以获得上下文更多信息。

实现方式:增量聚合算子中传入两个参数,比如aggregate,传入AggregateFunction和ProcessWindowFunction。aggregate计算完的结果传入到ProcessWindowFunction,只有一条结果

六、其他API

1)触发器(Trigger)

    主要用来控制窗口什么时候触发计算。基于.window之上嗲用.trigger方法,可以传入一个自定义的窗口触发器。会通过Trigger.FIRE方法进行触发

2)移除器 (Evictor)

    主要用来定义移除某些数据的逻辑。基于WindowedStream调用.evictor()方法,可以传入一个自定义的移除器。Evictor是一个接口,不同的窗口类型都有各自预实现的移除器

七、窗口的划分及生命周期(查看源码)

    1. 点击窗口分配器进入源码

     2. 找到assignWindows方法

 进入getStaggerOffset方法,查看计算start规则

1) start

remainder计算方法:

    例如当前时间为13s,窗口大小为10s,其中offset默认是0,用当前13 % 10 = 3,remainder>0走else路线,返回13 - 3 = 10。

    总结:start最终就要取窗口长度的整数倍。eg:10s -> 20s、30s...
  1. end

end = start + 窗口长度(窗口时左闭又开的)

属于本窗口的 最大时间戳是end - 1ms(源码中定义的)

3)生命周期

创建:属于本窗口范围的第一条数据来的时候,现new的(如上图new TimeWindow)

    思考:那是否再来这个区间的数据还会new呢?

        当然不会,使用的singletonList单例集合

销毁:关窗, 时间的进展 >= 窗口的最大时间戳(end - 1ms) + 允许迟到的时间(默认为0 )

标签: flink

本文转载自: https://blog.csdn.net/m0_72566748/article/details/142583675
版权归原作者 大数据领军人 所有, 如有侵权,请联系我们删除。

“Flink 窗口最全汇总”的评论:

还没有评论