一、背景
Flink在流处理过程中,数据不断进来,我们需要在一个时间段内进行维度上对数据进行聚合(窗口),Flink提供了Tumbling Windows(无重叠)、Sliding Windows(有重叠)、Session Windows(无重叠) 三种窗口类型,窗口 驱动主要分为(时间、数量)两种,根据我们实际的业务场景选择不同的窗口类型。
二、时间
我们基于特定时间段进行聚合时,可以引用不同的时间类型,Flink 最新版本提供了Event Time、Processing Time 两种时间类型。
来源官方图片
- Event Time :事件时间是每个事件在其生产设备上发生的时间。这个时间通常是放在记录.中,并且可以从纪录中获取时间时间戳。事件在flink 流转时,有时因为网络、 资源等,产生一些乱序,获取到时间乱序,为了数据更准确,Flink 提供了水 位 线WaterMark)来跟踪Event Time
- Processing Time :处理时间是执行相应操作的机器的系统时间,flink task处理数据的时 间,不会出现时间乱序,有着最好的性能和最低的延迟,数据结果可能 得到不一致的情况
三、滚动窗口(Tumbling Windows)
滚动窗口将每个元素分配给指定窗口大小的窗口。滚动窗口具有固定大小并且不重叠。例如,如果指定一个大小为 5 分钟的滚动窗口,则将评估当前窗口,并每隔五分钟启动一个新窗口,如下图所示。
来源官方图片
例如我们经常统计5秒用户点击了多少次数等这样的场景,每个人运用的场景不一样,事件时间举例子说明比较清晰:
1、我们采用事件时间,window的触发机制,是按照时间的划分,如果window设置5秒,那么20秒会把window划分为如下的形式:
[00:15:10 00:15:15) ->[1642263310000,1642263315000)
[00:15:15 00:15:20) ->[1642263315000,1642263320000)
2、通过程序验证,顺序发送10条数据
发送数据
{"key":"002","time":1642263310000}
{"key":"002","time":1642263311000}
{"key":"002","time":1642263313000}
{"key":"002","time":1642263315000}
{"key":"002","time":1642263316000}
{"key":"002","time":1642263317000}
{"key":"002","time":1642263318000}
{"key":"002","time":1642263319000}
{"key":"002","time":1642263320000}
窗口统计的执行结果
7> (002,3,1642263310000,1642263315000)
7> (002,5,1642263315000,1642263320000)
说明:1、002是key,3是数据量,后面两个[1642263310000,1642263315000)分别代表窗口的开始时间和结束时间
2、002是key,5是数据量,后面两个[1642263315000,1642263320000)分别代表窗口的开始时间和结束时间
四、滑动窗口(Sliding Windows)
滑动窗口将元素分配给固定长度的窗口。类似于滚动窗口,窗口的大小由窗口大小参数配置。一个附加的窗口滑动参数控制滑动窗口的启动频率。因此,如果window size parameter小于窗口大小,则滑动窗口可能会重叠。在这种情况下,元素被分配给多个窗口。例如,大小为 10 分钟的窗口滑动 5 分钟,每 5 分钟就会获得一个窗口,其中包含在最后 10 分钟内到达的事件,如下图所示。
来源官方图片
这个我们比较少用,这边先不做说明,后面需要在补上
五、会话窗口(Session Windows)
会话窗口按活动会话对元素进行分组。与滚动窗口和滑动窗口相比,会话窗口不重叠,也没有固定的开始和结束时间。相反,当会话窗口在一段时间内没有接收到元素时,即当出现不活动间隙时,会话窗口将关闭。会话窗口可以配置有会话间隙功能,该功能定义不活动的时间长度。当此期限到期时,当前会话关闭,后续元素被分配到新的会话窗口。
来源官方图片
例如用户在5秒内没在点击,认为这个用户不活跃,那么通过会话窗口进行统计,事件时间举例子说明比较清晰:
1、我们采用事件时间,window的触发机制,是按照时间的划分,如果window设置5秒
发送数据:
{"key":"001","time":1642263313000}
{"key":"001","time":1642263316000}
{"key":"001","time":1642263320000}
{"key":"001","time":1642263325000}
{"key":"001","time":1642263331000}
{"key":"001","time":1642263338000}
window划分为如下的形式:
[1642263313000,1642263330000)
[1642263331000,1642263336000)
结果说明
1> (001,4,1642263313000,1642263330000)
1> (001,1,1642263331000,1642263336000)
结果说明(第一个结果):第一条跟第二条相差3秒(1642263313000-1642263316000),没有触发
第二条跟第三条相差4秒(1642263316000-1642263320000),没有触发
第三条跟第4条相差5秒(1642263320000-1642263325000),没有触发
第四条跟第5条相差6秒(1642263325000-1642263331000)>gap(5秒),触发窗口
统计结果是前面4条数据
六、总结
我们对窗口的简单介绍(后面也会继续完善),没很复杂,比较能快速理解,后面会有实际的例子,对代码会有更好的理解、还有水位线的介绍