Flink的静态和动态的Session会话窗口(基于事件和处理时间案例)

本文详细解释了会话窗口在ApacheFlink中的工作原理,区分了静态和动态间隙,以及它们在事件时间和处理时间环境下的应用。通过代码示例展示了如何在实际场景中使用会话窗口进行数据聚合。
摘要由CSDN通过智能技术生成

Session Windows

会话窗口原理

  • 会话窗口根据会话的活跃元素情况进行分组,类似于web应用的Session,超过Session生命周期不访问,Session就关闭,下次发访问生成新的会话,对应Flink就是一段时间(session gap间隙)没有接收到新数据,即当一个不活动间隙发生时就会关闭上一个窗口,后续数据会分配到新的窗口,session gap间隙分为两种,一种时static session gap静态间隙,即间隙不变,一种是dynamic session gap动态间隙,即间隙不固定。

会话窗口的特点

  • 与滚动窗口和滑动窗口不同,会话窗口没有重叠
  • 时间无对齐,也没有固定的开始和结束时间
  • 只基于时间,不基于计数
  • 会话窗口分配器可以配置一个静态会话间隙,也可以配置一个会话间隙提取器函数,该函数定义了不固定会话间隙(动态会话间隙

会话窗口场景

  • 计算某个会话周期内的(session gap间隙)聚合数据

会话窗口示例图如下:
在这里插入图片描述

代码

如果不懂,需要看一下前面的“Time和Window”的文章 运行代码查看结果进行对比

package 复习
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala.function.ProcessWindowFunction
import org.apache.flink.streaming.api.windowing.assigners.{EventTimeSessionWindows, ProcessingTimeSessionWindows, SessionWindowTimeGapExtractor}
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector

/**
 *session Windows 会话窗口
 *处理时间滚动窗口输入数据:
2022-5-18 beijing 1648806746000 3
2022-5-18 beijing 1648806749000 3
2022-5-18 beijing 1648806751000 3
2022-5-18 beijing 1648806752000 2
2022-5-18 beijing 1648806757000 2
 */

object Session_Window {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) // 注意:在事件时间中一定设置并行度,否则需要大量数据才能看到效果
    val ds = env.socketTextStream("localhost", 6666)
      .map(x => {
        val fields: Array[String] = x.split(" ")
        val date = fields(0).trim
        val province = fields(1)
        val ts = fields(2).trim.toLong
        val dynamicGap = fields(3).trim.toInt
        (date + "_" + province, ts,dynamicGap)
      })
//      设置超时,为了事件时间提取时间戳还可以设置延迟
      .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[(String, Long, Int)](Time.seconds(0)) {
        override def extractTimestamp(t: (String, Long, Int)): Long = t._2
      })
      .keyBy(x=>x._1)

//      静态间隙基于事件时间的会话窗口
//      .window(EventTimeSessionWindows.withGap(Time.seconds(5)))

//      动态间隙基于事件时间的会话窗口
//      .window(EventTimeSessionWindows.withDynamicGap(new SessionWindowTimeGapExtractor[(String,Long,Int)] {
//        override def extract(t: (String, Long, Int)): Long = t._3*1000l
//      }))

//      静态间隙基于处理时间的会话窗口
//      .window(ProcessingTimeSessionWindows.withGap(Time.seconds(5)))

//      动态间隙基于处理时间的会话窗口   这里的范型是输入的类型

      .window(ProcessingTimeSessionWindows.withDynamicGap(new SessionWindowTimeGapExtractor[(String,Long,Int)] {
        override def extract(t: (String, Long, Int)): Long =t._3*1000l
      }))
      .process(new ProcessWindowFunction[(String,Long,Int),String,String,TimeWindow] {
        override def process(key: String, context: Context, elements: Iterable[(String, Long, Int)], out: Collector[String]): Unit = {
          val start = context.window.getStart
          val end = context.window.getEnd
          out.collect(s"""累计开始时间:${start},累计结束时间: ${end}, 数据条数:${elements.size},数据内容:${elements}""".stripMargin)
        }
      }).print()


    env.execute("test 06")
  }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值