这是我参与「第四届青训营 」笔记创作活动的的第五天
一、为什么需要Window
在流处理应用中,数据是连续不断的,有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的网页。在这种情况下,我们必须定义一个窗口(window),用来收集最近1分钟内的数据,并对这个窗口内的数据进行计算。
Flink 认为 Batch 是 Streaming 的一个特例,所以Flink是在底层的流式引擎上实现了流处理和批处理。而窗口(window)就是从 Streaming 到 Batch 的一个桥梁。
在 Flink 中 Window 可以将无限流切分成有限流,是处理有限流的核心组件,Flink 提供了非常完善的窗口机制。
在 Flink 中 Window 可以是时间驱动的(Time Window),也可以是数据驱动的(Count Window)
二、理解什么是Window
我们先提出一个问题:统计经过某红绿灯的汽车数量之和?
假设在一个红绿灯处,我们每隔15秒统计一次通过此红绿灯的汽车数量,如下图:
可以把汽车的经过看成一个流,无穷的流,不断有汽车经过此红绿灯,因此无法统计总共的汽车数量。但是,我们可以换一种思路,每隔15秒,我们都将与上一次的结果进行sum操作(滑动聚合, 但是这个结果似乎还是无法回答我们的问题,根本原因在于流是无界的,我们不能限制流,但可以在有一个有界的范围内处理无界的流数据。
滑动窗口:窗口长度:15s, 滑动的间隔:15s ---这样一个特殊的窗口长度=滑动的间隔的窗口也叫做滚动窗口
因此,我们需要换一个问题的提法:每隔15秒统计一次每分钟经过某红绿灯的汽车数量之和?
这个问题,就相当于一个定义了一个Window(窗口),window的界限是1分钟,且每分钟内的数据互不干扰,因此也可以称为翻滚(不重合)窗口,如下图:
第一分钟的数量为8,第二分钟是22,第三分钟是27。。。这样,1个小时内会有60个window。
再考虑一种情况,每30秒统计一次过去1分钟的汽车数量之和:
滑动窗口:窗口长度:1min, 滑动的间隔:30s
此时,window出现了重合。这样,1个小时内会有120个window。
三、Flink支持的窗口划分方式
如果在数据流上,截取固定大小的一部分,这部分是可以进行统计的。
截取方式主要有两种:
1.Flink支持两种划分窗口的方式(time和count)
如果根据时间划分窗口,那么它就是一个time-window,比如每1分钟统计一次或每10分钟统计一次(和之前学习的一模一样)
如果根据数据划分窗口,那么它就是一个count-window,比如每5个数据统计一次或每50个数据统计一次
2.Flink支持窗口的两个重要属性(窗口长度size和滑动间隔interval)
如果size=interval,那么就会形成tumbling-window(无重叠数据)--滑动的特例--滚动窗口
如果size(1min)>interval(30s),那么就会形成sliding-window(有重叠数据)--正常的滑动窗口
如果size<interval,那么这种窗口将会丢失数据。比如每5秒钟,统计过去3秒的通过路口汽车的数据,将会漏掉2秒钟的数据。
3.通过组合可以得出四种基本窗口
time-tumbling-window 无重叠数据的时间窗口,设置方式举例:timeWindow(Time.seconds(5))---基于时间的滚动窗口
time-sliding-window 有重叠数据的时间窗口,设置方式举例:timeWindow(Time.seconds(10), Time.seconds(5))---基于时间的滑动窗口
count-tumbling-window无重叠数据的数量窗口,设置方式举例:countWindow(5)---基于数量的滚动窗口
count-sliding-window 有重叠数据的数量窗口,设置方式举例:countWindow(10,5)---基于数量的滑动窗口
注意:Flink中还支持一个特殊的窗口:会话窗口SessionWindows
四、总结
我们先举例统计经过某红路灯的汽车数量可以深刻理解流计算中的Window,通过提出问题用不同方法统计车流量即为定义了不同的Window。在Flink中通过基于时间和基于数据去截取数据来划分窗口。通过不同的组合可以得到四种基本窗口。