Apache Flink中流处理之Window详解.

1.关于Window

1.1Window概述

Windows are at the heart of processing infinite streams. Windows split the stream into “buckets” of finite size, over which we can applycomputations.

从官网的翻译来看意思为:窗口是处理无限流的核心。Windows将流拆分为大小有限的“bucket”,我们可以将其应用于计算。

1.2Window的类型

关于Window的可以分成两类:
1.CountWindow:按照指定的数据条数生成一个Window,与时间无关。
2. TimeWindow:按照时间生成Window。
对于TimeWindow,可以根据窗口实现原理的不同分成三类:滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)和会话窗口(Session Window)。

1.2.1关于TimeWindow的详细描述

1.滚动窗口:将数据依据固定的窗口长度对数据进行切片(在本质上它是属于一种特殊的滑动窗口)。
特点:时间对齐,窗口长度固定,没有重叠

在这里插入图片描述

2.滑动窗口: 滑动窗口是固定窗口的更广义的一种形式,滑动窗口由固定的窗口长度和滑动间隔(即滑动步长)组成。

特点:时间对齐,窗口长度固定,可以有重叠

在这里插入图片描述

3.会话窗口:由一系列事件组合一个指定时间长度的timeout间隙组成,类似于web应用的session,也就是一段时间没有接收到新数据就会生成新的窗口。

特点:时间无对齐

在这里插入图片描述

1.2.2关于窗口式Flink程序

1.keyed-stream:

stream
       .keyBy(...)               <-  keyed versus non-keyed windows
       .window(...)              <-  required: "assigner"
      [.trigger(...)]            <-  optional: "trigger" (else default trigger)
      [.evictor(...)]            <-  optional: "evictor" (else no evictor)
      [.allowedLateness(...)]    <-  optional: "lateness" (else zero)
      [.sideOutputLateData(...)] <-  optional: "output tag" (else no side output for late data)
       .reduce/aggregate/fold/apply()      <-  required: "function"
      [.getSideOutput(...)]      <-  optional: "output tag"

2.no keyed-stream:

stream
       .windowAll(...)           <-  required: "assigner"
      [.trigger(...)]            <-  optional: "trigger" (else default trigger)
      [.evictor(...)]            <-  optional: "evictor" (else no evictor)
      [.allowedLateness(...)]    <-  optional: "lateness" (else zero)
      [.sideOutputLateData(...)] <-  optional: "output tag" (else no side output for late data)
       .reduce/aggregate/fold/apply()      <-  required: "function"
      [.getSideOutput(...)]      <-  optional: "output tag"

注意一般情况下我们都是将DataStream转换为KeyedStream在进行相应的计算,no keyed-stream用的相对较少

1.3WindowAPI测试

需求:每隔60s计算各个温度计中温度的最小值,并输出最新的时间戳

package com.mo.apiTest

import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.assigners.{
    
    EventTimeSessionWindows, SlidingEventTimeWindows, TumblingEventTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time


case class thermometer(id : String ,time :String,Temp : Double)
//温度计样例类
object Time_window {
    
    
  def main(args: Array[String]): Unit = {
    
    

    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)
    //从socket文本流中读取数据
    val inputStream = env.socketTextStream("hadoop102",7777)

    // 先转换成样例类类型
    val dataStream = inputStream
      .map( data => {
    
    
        val arr = data.split(",")
        thermometer(arr(0), arr(1), arr(2).toDouble)
      } )

    val res = dataStream
      .map(data => (data.id,data.Temp,data.time))
      .keyBy(_._1)   //按照id进行分组
//      .window(TumblingEventTimeWindows.of(Time.seconds(15)))  底层滚动窗口的实现
//      .window(SlidingEventTimeWindows.of(Time.seconds(15),Time.milliseconds(3))) //底层滑动窗口的实现
//      .window(EventTimeSessionWindows.withGap(Time.seconds(15)))  会话窗口
//      .countWindow(10)  滚动计数窗口
//      .countWindow(10,2) 滑动计数窗口
      .timeWindow(Time.seconds(60))  //使用Flink为我们封装好的滑动或者滚动窗口的实现方法
      .reduce((currdata,newdata)=>(currdata._1,currdata._2.min(newdata._2),newdata._3))  //每60s求出当前时间下各个温度计的最小值,并更新当前最新的时间戳

    res.print()
    env.execute("Tumblingwindow test")

  }
}

运行截图:

在这里插入图片描述

在这里插入图片描述
可以看到此时输出的都是每隔60s内每种温度计的最小温度值和当前最新的时间戳

猜你喜欢

转载自blog.csdn.net/weixin_44080445/article/details/112156744