一 Flink 中的 Window
1 Window
(1)Window概述

streaming流式计算是一种被设计用于处理无限数据集的数据处理引擎,而无限数据集是指一种不断增长的本质上无限的数据集,而window是一种切割无限数据为有限块进行处理的手段。
Window是无限数据流处理的核心,Window将一个无限的stream拆分成有限大小的”buckets”桶,我们可以在这些桶上做计算操作。
(2) Window类型
Window可以分成两类:
-
CountWindow:计数窗口,按照指定的数据条数生成一个Window,与时间无关。
-
TimeWindow:时间窗口,按照时间生成Window。
对于TimeWindow,可以根据窗口实现原理的不同分成三类:
- 滚动窗口(Tumbling Window):是滑动窗口的特殊形式,是窗口大小和滑动距离相同的滑动窗口。
- 滑动窗口(Sliding Window):窗口间可以重叠。
- 会话窗口(Session Window):只有 Flink 支持。
a 滚动窗口(Tumbling Windows)
将数据依据固定的窗口长度对数据进行切片。
特点:时间对齐,窗口长度固定,没有重叠。
滚动窗口分配器将每个元素分配到一个指定窗口大小的窗口中,滚动窗口有一个固定的大小,并且不会出现重叠。例如:如果指定了一个5分钟大小的滚动窗口,窗口的创建如下图所示:
注意:先分流再开窗,在每个支流上开窗口,每个支流上的窗口之间没有关系。

适用场景:适合做BI统计等(做每个时间段的聚合计算)。
b 滑动窗口(Sliding Windows)
滑动窗口是固定窗口的更广义的一种形式,滑动窗口由固定的窗口长度和滑动间隔组成。
特点:时间对齐,窗口长度固定,可以有重叠。
滑动窗口分配器将元素分配到固定长度的窗口中,与滚动窗口类似,窗口的大小由窗口大小参数来配置,另一个窗口滑动参数控制滑动窗口开始的频率。因此,滑动窗口如果滑动参数小于窗口大小的话,窗口是可以重叠的,在这种情况下元素会被分配到多个窗口中。
在Flink底层,其将处于不同窗口中的元素进行复制处理,然后分发到不同窗口中,所以需要合理分配窗口大小和滑动距离,若窗口大小为一天,滑动距离为一秒,同一份数据可能存在于几千个窗口中,内存可能会崩溃。
例如假如有10分钟的窗口和5分钟的滑动,那么每个窗口中5分钟的窗口里包含着上个10分钟产生的数据,如下图所示:

适用场景:对最近一个时间段内的数据进行统计(求某接口最近5min的失败率来决定是否要报警)。
c 会话窗口(Session Windows)
由一系列事件组合一个指定时间长度的timeout间隙组成,类似于web应用的session,也就是一段时间没有接收到新数据就会生成新的窗口。
特点:时间无对齐。
session窗口分配器通过session活动来对元素进行分组,session窗口跟滚动窗口和滑动窗口相比,不会有重叠和固定的开始时间和结束时间的情况,相反,当它在一个固定的时间周期内不再收到元素,即非活动间隔产生,那个这个窗口就会关闭。
一个session窗口通过一个session间隔来配置,这个session间隔定义了非活跃周期的长度,当这个非活跃周期产生,那么当前的session将关闭并且后续的元素将被分配到新的session窗口中去。
只有 Flink 支持会话窗口。
在某些场景下,使用会话窗口可以更加精确的刻画用户行为,如刷抖音。

2 Window API
窗口分配器——window() 方法
可以用.window() 来定义一个窗口,然后基于这个window 去做一些聚合或者其它处理操作。
(1)处理时间窗口
a 滚动窗口
.window(TumblingProcessingTimeWindows.of(Time.seconds(5))):默认开的第一个窗口是在1970-01-01 00:00:00 - 1970-01-01 00:00:05,在这种情况下窗口不会开在3s - 8s时间段。
使用处理时间窗口中的滚动窗口实现求每个用户的pv:
public static void main(String[] args) throws Exception{
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
env
.addSource(new ClickSource())
.keyBy(r -> r.user)
.window(TumblingProcessingTimeWindows.of(Time.seconds(5)))
.process(new WindowResult())
.print();
env.execute();
}
// 泛型依次为:输入的泛型,输出的泛型,key的泛型,窗口的泛型
public static class WindowResult extends ProcessWindowFunction<Event,String,String, TimeWindow>{
// 在窗口关闭的时候,触发调用,只会调用一次
// 对于机器时间,运行到窗口结束时间就会关闭窗口
@Override
// 迭代器参数中包含了窗口中的全部元素
public void process(String key, Context context, Iterable<Event> iterable, Collector<String> collector) throws Exception {
long windowStart = context.window().getStart(

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



