理论

  • 1.window(窗口)概述:
    streaming流式计算是一种被设计用于处理无限数据集的数据处理引擎, 而无限数据集是值一种不断增长的本质上无限的数据集, 而window是一种切割无限数据为有限块进行处理的手段
  • 2.window可以分为两种: 计数窗口(CountWindow)和时间窗口(TimeWindow)

滚动窗口: 比如指定5分钟大小的窗口,窗口之间没有数据重叠,长度固定
滑动窗口:窗口之间的数据会有重叠
会话窗口:设定时间阈值,当超过这个时间,没有数据到来的话,会生成新的窗口

  • 水位线: 当我们使用事件时间进行处理时,会出现因为网络丶分布式等问题,数据产生乱序,但是我们又不能无限期的等下去,我们需要设定一个条件, 当达到时,就去强制计算window的内容,这个就叫做水位线(watemark),可以理解为是一个延迟触发机制

水位线例子讲解:

图解:

flink滚动窗口 兼容 flink滚动窗口0点清零_flink

像上面的数据, 当数据来临时, 我们设置水位线延迟时间为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
      })