什么是窗口函数

FlinkSQL支持对一个特定的窗口的聚合。例如有用户想统计在过去的1分钟内有多少用户点击了某个的网页。在这种情况下,我们可以定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。FlinkSQL支持的窗口聚合主要是两种:window aggregate,和over aggregate。他们最核心的区别是over aggregate从语义上保障了对每个输入都有一个输出,因此over agregate常被用于ranking,moving average等场景。关于over aggregate的细节可以参考后面的over aggregate的session章。本节下来主要介绍window aggregate。Window aggregate支持两种时间类型做窗口:Event Time和Processing Time。每种类型下,又分别支持三种窗口类型:滚动窗口(TUMBLE),滑动窗口(HOP),和会话窗口(SESSION)。

时间类型
BlinkSQL支持两种时间:
 
1. Event Time:用户提供的事件时间(通常是数据的最原始的创建时间),event time一定是用户提供在表的schema里的数据
 
2. Processing Time:表示系统对事件进行处理的本地系统时间下图中是不同时间属性在流上的概念:
 
从上面的定义可以看出,ingestion time和 processing time是系统为流记录增加的时间属性,用户并不能控制。EventTime则是流记录本身携带的时间属性,但由于数据本身有乱序,加之网络抖动或其它原因,eventTime为t1时刻的纪录,有可能会晚于t2(t2 > t1)时刻的被Flink处理。
 
基于processing time的Aggregate
processing time是系统产生的,不在用户的原始数据中,实时计算Streaming无需显示定义一个processtime,下面给出一个基于processing time的Aggregat例子:
 
SELECT COUNT(amount) OVER ( PARTITION BY user
 
ORDER BY proctime
 
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
 
FROM Orders
 
基于Event Time的Aggregate
event time是用户的原始数据,我们不需要显式重新定义一个event time列, 但是我们要求用户必须指定watermark的计算方法。这是因为用户的数据往往是乱序的,如果不配置一个watermark来合理的delay用户数据,那样数据聚合的结果往往都有很大的偏差,详情请参考https://dtstack.yuque.com/pd2/avoo30/watermark[watermark]。
 
实时计算中的窗口类型
目前实时计算全面支持Flink三种窗口类型,通过不同窗口类型的使用可覆盖绝大多数使用场景。
 
滚动窗口(Tumble Window)
滚动窗口将每个元素分配到一个指定窗口大小的窗口中,滚动窗口有一个固定的大小,并且不会出现重叠。例如:如果指定了一个5分钟大小的滚动窗口,那么无限流的数据会根据时间划分成[0:00 - 0:05), [0:05, 0:10), [0:10, 0:15)… 等窗口。如下图展示了一个 30秒大小的滚动窗口划分。
 
窗口函数语法
 
用在GROUP BY子句中,定义window。
 
TUMBLE(time_attr, size_interval)
 
1. time_attr:参数必须是流中的一个合法的时间属性字段,即指定了 processing time 或是 event time;
 
2. size_interval:窗口时间间隔;
 
滑动窗口(Slide Window)
滑动窗口,也被称作 Sliding Window。不同于滚动窗口的窗口不重叠,滑动窗口的窗口可以重叠。滑动窗口有两个参数:size 和 slide。size 为窗口的大小,slide 为每次滑动的步长。如果slide < size,则窗口会重叠,每个元素会被分配到多个窗口;如果 slide = size,则等同于TUMBLE。如果 slide > size,则为跳跃窗口,窗口之间没有重叠且有间隙。因为多个窗口是重叠的,大部分元素属于多个窗口。这种窗口在计算移动平均数(moving averages)是很实用的。例如,计算过去5分钟数据的平均值,每10秒钟更新一次,那么size=5分钟,slide=10秒钟。如下图所示展示一个1分钟窗口大小,每30秒滑动一次的滑动窗口。
 
窗口函数语法
 
用在GROUP BY子句中,定义window。
 
TUMBLE(time_attr, slide_interval, size_interval)
 
1.time_attr:参数必须是流中的一个合法的时间属性字段,即指定了 processing time 或是 event time;
 
2.slide_interval:滑动窗口的滑动时间间隔;
 
3.size_interval:滑动窗口的固定时间间隔;
 
会话窗口(Session Window)
会话窗口通过session活动来对元素进行分组,会话窗口跟滚动窗口和滑动窗口相比,没有窗口重叠,没有固定窗口大小。相反,当它在一个固定的时间周期内不再收到元素,即会话断开,那这个窗口就会关闭。一个会话窗口通过一个间隔时间(gap)来配置,这个间隔定义了非活跃周期的长度。例如,一个表示鼠标点击活动的数据流可能具有长时间的空闲时间,并在其间散布着高浓度的点击。 如果数据在最短指定的间隔持续时间之后到达,则会开始一个新的窗口。如下图所示,展示了会话窗口,注意每个 key 由于不同的数据分布有不同的 window。

窗口函数语法
 
用在GROUP BY子句中,定义window。
 
SESSION(time_attr, gap_interval)
 
1.time_attr:参数必须是流中的一个合法的时间属性字段,即指定了 processing time 或是 event time;
 
2.gap_interval:会话窗口的gap时间间隔;