理论
- 1.window(窗口)概述:
streaming流式计算是一种被设计用于处理无限数据集的数据处理引擎, 而无限数据集是值一种不断增长的本质上无限的数据集, 而window是一种切割无限数据为有限块进行处理的手段 - 2.window可以分为两种: 计数窗口(CountWindow)和时间窗口(TimeWindow)
滚动窗口:
比如指定5分钟大小的窗口,窗口之间没有数据重叠,长度固定滑动窗口:
窗口之间的数据会有重叠会话窗口:
设定时间阈值,当超过这个时间,没有数据到来的话,会生成新的窗口
- 水位线: 当我们使用事件时间进行处理时,会出现因为网络丶分布式等问题,数据产生乱序,但是我们又不能无限期的等下去,我们需要设定一个条件, 当达到时,就去强制计算window的内容,这个就叫做
水位线(watemark)
,可以理解为是一个延迟触发机制
水位线例子讲解:
图解:
像上面的数据, 当数据来临时, 我们设置水位线延迟时间为2s,当第7s的数据来临时,此时水位线为5s, 这时候就会关闭1-5s的这个窗口,当第12s的数据来临时,此时水位线为10s,这个时候就会关闭5-10s的这个窗口
注意: 窗口的数据是[1,5),左闭右开
作用: 主要是为了保证数据的准确性
实操
前提: 一般我们都会设置处理数据时为事件时间
,默认为系统处理时间
val env = StreamExecutionEnvironment.getExecutionEnvironment
//设置为事件时间
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
窗口的设定:
val result = streamData
.map(item => (item.id, item.timestamp, item.temperature))
.keyBy(_._1)
// ====窗口的几种方式(window)====
// .window( TumblingEventTimeWindows.of(Time.seconds(10))) //滚动时间窗口
// .window( SlidingEventTimeWindows.of(Time.seconds(15),Time.seconds(3))) // 滑动时间窗口
// .window( EventTimeSessionWindows.withGap(Time.seconds(15))) // 会话时间窗口 参数: 时间间隙,如果没来数据,会生成新的窗口
// .timeWindow(Time.seconds(15)) //简单写法:滚动时间窗口
// .timeWindow(Time.seconds(15),Time.seconds(3)) 简单写法:滑动时间窗口
// .countWindow(3) // 滚动计数窗口
//.countWindow(15,2) // 滑动计数窗口
水位线的设置:
val streamData = data.map(item => {
val strs = item.split(",")
SensorReading(strs(0), strs(1).toLong, strs(2).toDouble)
})
// ===========Watermark(水位线)的设置===========
// 1.升序数据提取时间戳(一般都为毫秒数
// .assignAscendingTimestamps( _.timestamp*1000L) )
// 2.乱序数据提取时间戳(周期性设置水位线), 参数: 延迟时间,过大的话,影响性能
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(3)) { override def extractTimestamp(element: SensorReading): Long = element.timestamp*1000L
})