【Flink】(三)Flink Window 窗口机制

Flink Window 窗口机制

一、总览

  • Window 是flink处理无限流的核心,Windows将流拆分为有限大小的“桶”,我们可以在其上应用计算。

  • Flink 认为 Batch 是 Streaming 的一个特例,所以 Flink 底层引擎是一个流式引擎,在上面实现了流处理和批处理。

  • 而窗口(window)就是从 Streaming 到 Batch 的一个桥梁。

  • Flink 提供了非常完善的窗口机制。

  • 在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理。

  • 当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的网页。

  • 在这种情况下,我们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。

  • 窗口可以是基于时间驱动的(Time Window,例如:每30秒钟)

  • 也可以是基于数据驱动的(Count Window,例如:每一百个元素)

  • 同时基于不同事件驱动的窗口又可以分成以下几类:

    • 翻滚窗口 (Tumbling Window, 无重叠):一条记录只属于一个窗口
    • 滑动窗口 (Sliding Window, 有重叠):一条记录属于多个窗口
    • 会话窗口 (Session Window, 活动间隙):一条记录一个窗口
    • 全局窗口 (略)
  • Flink要操作窗口,先得将StreamSource 转成WindowedStream
    在这里插入图片描述

二、Tumbling Window(翻滚窗口)

  • 翻滚窗口能将数据流切分成不重叠的窗口,每一个事件只能属于一个窗口

  • 翻滚窗具有固定的尺寸,不重叠。

  • 例图:
    在这里插入图片描述

  • 基于时间驱动 timeWindow(Time.seconds(n))

  • 基于事件驱动 countWindow(n)

案例:

package cn.kgc.kb09.Window
import cn.kgc.kb09.Tramsfrom.WaterSensor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow

/**
  * Flink 窗口函数
  * Tumbling Window (滚动窗口)  窗口周期 10秒
  * 找出最小空高
  *
  * 从socket端口接收字符串格式为"sensor_1,1549044122,10"数据
  * 接收到字符串后将字符串流转换成WaterSensor流  DataStream[WaterSensor]
  */

// 定义样例类
case class WaterSensor(id:String,ts:Long,vc:Double)

object WindowDemo {
  def main(args: Array[String]): Unit = {
    // 创建执行的环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) // 设置并行度

    // 从socket端口接收数据
    val stream = env.socketTextStream("192.168.247.201",7777)

    // 转换成样例类
    val dataStream = stream.map(x => {
      // 根据逗号切割 获取每个元素
      val strings = x.split(",")
      WaterSensor(strings(0).trim, strings(1).trim.toLong, strings(2).trim.toDouble)
    })

    val dataStream2: DataStream[(String, Double)] = dataStream.map(data => (data.id, data.vc))

    val dataStream3: KeyedStream[(String, Double), String] = dataStream2.keyBy(_._1)


    // Tumbling Window  滚动窗口
    val dataStream4: WindowedStream[(String, Double), String, TimeWindow] = dataStream3.timeWindow(Time.seconds(10))

    val minDataStream: DataStream[(String, Double)] = dataStream4.reduce((x, y) => (x._1,x._2.min(y._2)))

    // 打印
    dataStream.print("orig")
    minDataStream.print("min")

    // 执行
    env.execute("windowDemo")
  }
}

运行代码,在Linux上执行nc -lk 7777命令
在这里插入图片描述
在这里插入图片描述

三、Sliding Window(滑动窗口)

  • 滑动窗口和翻滚窗口类似,区别在于:滑动窗口可以有重叠的部分。

  • 在滑窗中,一个元素可以对应多个窗口。

  • 例图:

在这里插入图片描述

  • 基于时间驱动 timeWindow(Time.seconds(n), Time.seconds(m))

  • 基于事件驱动 countWindow(n, m)

案例:

package cn.kgc.kb09.Window
import cn.kgc.kb09.Tramsfrom.WaterSensor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow

/**
  * Flink 窗口函数
  * Sliding Window  (滑动窗口)  窗口周期 10秒  滑动周期 5秒
  * 找出最小空高
  *
  * 从socket端口接收字符串格式为"sensor_1,1549044122,10"数据
  * 接收到字符串后将字符串流转换成WaterSensor流  DataStream[WaterSensor]
  */


// 定义样例类
case class WaterSensor(id:String,ts:Long,vc:Double)

object WindowDemo {
  def main(args: Array[String]): Unit = {
    // 创建执行的环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) // 设置并行度

    // 从socket端口接收数据
    val stream = env.socketTextStream("192.168.247.201",7777)

    // 转换成样例类
    val dataStream = stream.map(x => {
      // 根据逗号切割 获取每个元素
      val strings = x.split(",")
      WaterSensor(strings(0).trim, strings(1).trim.toLong, strings(2).trim.toDouble)
    })

    val dataStream2: DataStream[(String, Double)] = dataStream.map(data => (data.id, data.vc))

    val dataStream3: KeyedStream[(String, Double), String] = dataStream2.keyBy(_._1)

    // Sliding Window  滑动窗口
    val dataStream4: WindowedStream[(String, Double), String, TimeWindow] = dataStream3.timeWindow(Time.seconds(10),Time.seconds(5))

    val minDataStream: DataStream[(String, Double)] = dataStream4.reduce((x, y) => (x._1,x._2.min(y._2)))


    // 打印
    dataStream.print("orig")
    minDataStream.print("min")

    // 执行
    env.execute("windowDemo")
  }
}

运行代码,在Linux上执行nc -lk 7777命令
在这里插入图片描述
在这里插入图片描述

四、Session Window(会话窗口)

  • 会话窗口不重叠,没有固定的开始和结束时间

  • 与翻滚窗口和滑动窗口相反, 当会话窗口在一段时间内没有接收到元素时会关闭会话窗口。

  • 后续的元素将会被分配给新的会话窗口

  • 例图:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值