一、窗口概念
将无界流切割为有界流的一种方式,它会将流数据分到有限大小的桶(bucket)中进行分析。
二、窗口类型
- 时间窗口
(1)滚动时间窗口
1)将数据依据固定的窗口长度对数据进行切分
2)特点:时间对齐,窗口长度固定,没有重叠
3)适用场景:适合做BI统计等(做每个时间段的聚合计算)。
4)窗口范围:左闭右开 [8:00,8:16)
5)参数包括:window size、time
(2)滑动时间窗口
1)滑动窗口是固定窗口的更广义的一种形式,滑动窗口由固定的窗口长度和滑动间隔组成
2)特点:窗口长度固定,可以有重叠
3)适用场景:对最近一个时间段内的统计(求某接口最近5min的失败率来决定是否要报警)。
4)参数包括:window size、window slide以及time
(3)会话窗口
1)由一系列事件组合一个指定时间长度的timeout间隔组合,也就是一段时间没有接收到新数据就会生成新的窗口
2)特点:时间无对齐
3)参数:time - 计数窗口
(1)滚动计数窗口
(2)滑动计数窗口
三、窗口API
(一)timewindow
是将指定时间范围内的所有数据组成一个window,一次对一个window里面的所有数据进行计算。
1.1 滚动窗口
1)方法描述:Flink默认的时间窗口根据process time进行窗口的划分,将flink获取到的数据根据进入flink的时间划分到不同的窗口中。时间间隔可以通过Time.milliseconds(x),Time.seconds(x),Time.minutes(x)等其中一个来指定。
2)创建不同类型的窗口(相当于是分桶操作)
·滚动时间窗口(tumbling time window):
.timeWindow(Time.seconds(15))
·滑动时间窗口(sliding time window):
.timeWindow(Time.seconds(15),Time.seconds(5))
·会话窗口(session window):
.window(EventTimeSessionWindows.withGap(Time.minutes(10)))
·滚动计数窗口(tumbling count window):
.countWindow(10)
·滑动计数窗口(sliding count window):
.countWindow(10,2)
val inputStream = env.socketTextStream("localhost", 7777)
val dataStream = inputStream
.map(data => {
val arr = data.split(",")
SensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
})
//每15秒统计一次,窗口内各传感器所有温度的最小值
val resultStream = dataStream
.map(data => (data.id, data.temperature))
.keyBy(data => data._1) //按照二元组的第一个元素id来分组
//.window(TumblingEventTimeWindows.of(Time.seconds(15))) //滚动时间窗口
//.window(SlidingProcessingTimeWindows.of(Time.seconds(15),Time.seconds(3))) //滑动时间窗口
//.window(EventTimeSessionWindows.withGap(Time.seconds(10))) //会话时间窗口
.timeWindow(Time.seconds(15))
//.countWindow(10) //滚动计数窗口
//minBy(1)
.reduce((r1, r2) => (r1._1, r1._2.min(r2._2)))
resultStream.print()
env.execute()