Flink 滑动窗口使用触发器会触发多个窗口的计算

Posted Flink菜鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flink 滑动窗口使用触发器会触发多个窗口的计算相关的知识,希望对你有一定的参考价值。

之前有小伙伴在群里说:滑动窗口使用触发器让每条数据都触发一次计算

但是他并没有得到预期的结果:每条数据都触发一次计算,输出一条结果,而是每天数据都输出了很多条结果

为什么会这样呢?

写了个小案例,来解释这种情况

为了方便使用自定义的 source 开发数据:

class StringSourceFunction extends SourceFunction[String] {

  var flag = true

  override def cancel(): Unit = {

    flag = false
  }

  override def run(ctx: SourceFunction.SourceContext[String]): Unit = {

    while (flag) {
      val str = StringUtil.getRandomString(1).toUpperCase
      ctx.collect(str + "," + StringUtil.getRandomString(1).toUpperCase)
      Thread.sleep(1000)
    }
  }

}

就是个简单的 souce,每秒对外发出随机的 string 字符串(基本一分钟 60 条)

对应的计算程序如下:

env.addSource(new StringSourceFunction)
      .windowAll(SlidingProcessingTimeWindows.of(Time.minutes(1), Time.seconds(10)))
      // 每条数据触发一次计算
      //.trigger(CountTrigger.of(1))
      .process(new ProcessAllWindowFunction[String, String, TimeWindow] {
      override def process(context: Context, elements: Iterable[String], out: Collector[String]): Unit = {
        // 窗口
        val window = context.window.toString
        // 简单计算下窗口里面的元素个数
        var count: Long = 0
        elements.iterator.foreach(s => count += 1)


        out.collect("time : " + sdf.format(System.currentTimeMillis()) + ", window : " + window + ", element counter : " + count)
      }
    })
      .print("")

定义了一个 一分钟的窗口,滑动间隔是10秒,一条数据就应该属于6个窗口

比如: 5 这条数据属于:(-50,10)(-40,20)(-30,30)(-20,40)(-10,50)(0,60) 这6 个窗口

注释 trigger 看结果:

10秒滑动间隔,就是10秒有一个滑动一次,一个窗口结束,触发一次计算,输出一个结果(前面6个窗口,因为刚启动数据不够60条)

开启了tirgger 结果就完全不一样了

可以看到,第一条数据进去的时候,触发了6次计算,因为它属于6个窗口,tirgger 会触发6次

 欢迎关注Flink菜鸟公众号,会不定期更新Flink(开发技术)相关的推文

 

以上是关于Flink 滑动窗口使用触发器会触发多个窗口的计算的主要内容,如果未能解决你的问题,请参考以下文章

从0到1Flink的成长之路(十九)-案例:计数窗口

flink窗口的种类及详述

flink-demo-根据事件时间触发窗口计算

flink-demo-根据事件时间触发窗口计算

flink 控制窗口行为(触发器移除器允许延迟将迟到的数据放入侧输出流)

flink 自定义触发器 定时或达到数量触发