Flink之窗口函数WindowFunction

前言

本文主要讲解下窗口函数:ReduceFunction,AggregateFunction,ProcessWindowFunction

ReduceFunction

是个增量计算的算子,数据来一条算一条,要求入参和出参类型一致这个要求导致条件苛刻。没有aggregate好用~
直接看代码:模拟订单,计算10s滚动窗口订单金额~~~使用起来比较简单的

package com.realtime.flink.function

import com.realtime.flink.dto.OrderDto
import com.realtime.flink.source.OrderSource
import org.apache.flink.api.common.functions.ReduceFunction
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.assigners.{GlobalWindows, TumblingEventTimeWindows, TumblingProcessingTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time

/**
 * 注意:reduce不能直接用Double,会报错
 * 数据时增量计算,来一条算一条
 */
object ReduceFunctionTest  {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.getConfig.setParallelism(1)

    env.addSource(new OrderSource)
      .windowAll(TumblingProcessingTimeWindows.of(Time.seconds(10)))
      .reduce(new ReduceFunction[OrderDto] {
        override def reduce(value1: OrderDto, value2: OrderDto): OrderDto = {
          value1.setOrderPrice(value1.getOrderPrice+value2.getOrderPrice)
          value1
        }
      })
        .map(x=>{
          println(x.getOrderPrice)
        })

    env.execute("tttt")
  }

}

输出结果:

AAAAAAAAAAA数据:2021-03-30 23:22:34-->1
AAAAAAAAAAA数据:2021-03-30 23:22:35-->7
AAAAAAAAAAA数据:2021-03-30 23:22:36-->4
AAAAAAAAAAA数据:2021-03-30 23:22:37-->9
AAAAAAAAAAA数据:2021-03-30 23:22:38-->7
AAAAAAAAAAA数据:2021-03-30 23:22:39-->1
29.0
AAAAAAAAAAA数据:2021-03-30 23:22:40-->6
AAAAAAAAAAA数据:2021-03-30 23:22:41-->1
AAAAAAAAAAA数据:2021-03-30 23:22:42-->6
AAAAAAAAAAA数据:2021-03-30 23:22:43-->6
AAAAAAAAAAA数据:2021-03-30 23:22:44-->5
AAAAAAAAAAA数据:2021-03-30 23:22:45-->4
AAAAAAAAAAA数据:2021-03-30 23:22:46-->3
AAAAAAAAAAA数据:2021-03-30 23:22:47-->6
AAAAAAAAAAA数据:2021-03-30 23:22:48-->9
AAAAAAAAAAA数据:2021-03-30 23:22:49-->0
46.0
AAAAAAAAAAA数据:2021-03-30 23:22:50-->8
AAAAAAAAAAA数据:2021-03-30 23:22:51-->7
AAAAAAAAAAA数据:2021-03-30 23:22:52-->0

AggregateFunction

也是个增量计算的算子,里面实现4个方法,也比较简单,用起来会比reduce更灵活。具体看代码注释~

package com.realtime.flink.function

import com.realtime.flink.dto.OrderDto
import com.realtime.flink.source.OrderSource
import org.apache.flink.api.common.functions.{AggregateFunction, ReduceFunction}
import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment, _}
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows
import org.apache.flink.streaming.api.windowing.time.Time

/**
 * 数据时增量计算,来一条算一条
 */
object AggregateFunctionTest  {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.getConfig.setParallelism(1)

    env.addSource(new OrderSource)
      .windowAll(TumblingProcessingTimeWindows.of(Time.seconds(10)))
      .aggregate(new AggregateFunction[OrderDto,Double,Double] {
        // 初始化
        override def createAccumulator(): Double = {
          0.0
        }
        // 窗口数据进来合并
        override def add(value: OrderDto, accumulator: Double): Double = {
          value.getOrderPrice+accumulator
        }
        // 返回结果
        override def getResult(accumulator: Double): Double = {
          accumulator
        }
        // 窗口合并,多并发情况下多个窗口结果合并输出,测试用例设置了并发数据为 1
        override def merge(a: Double, b: Double): Double = {
          a+b
        }
      })
      .print()

    env.execute("tttt")
  }

}

测试结果:

AAAAAAAAAAA数据:2021-03-30 23:34:23-->1
AAAAAAAAAAA数据:2021-03-30 23:34:24-->1
AAAAAAAAAAA数据:2021-03-30 23:34:25-->2
AAAAAAAAAAA数据:2021-03-30 23:34:26-->1
AAAAAAAAAAA数据:2021-03-30 23:34:27-->7
AAAAAAAAAAA数据:2021-03-30 23:34:28-->2
AAAAAAAAAAA数据:2021-03-30 23:34:29-->0
14.0
AAAAAAAAAAA数据:2021-03-30 23:34:30-->6
AAAAAAAAAAA数据:2021-03-30 23:34:31-->5
AAAAAAAAAAA数据:2021-03-30 23:34:32-->9
AAAAAAAAAAA数据:2021-03-30 23:34:33-->3
AAAAAAAAAAA数据:2021-03-30 23:34:34-->7
AAAAAAAAAAA数据:2021-03-30 23:34:35-->7
AAAAAAAAAAA数据:2021-03-30 23:34:36-->3
AAAAAAAAAAA数据:2021-03-30 23:34:37-->1
AAAAAAAAAAA数据:2021-03-30 23:34:38-->1
AAAAAAAAAAA数据:2021-03-30 23:34:39-->6
48.0
AAAAAAAAAAA数据:2021-03-30 23:34:40-->4
AAAAAAAAAAA数据:2021-03-30 23:34:41-->4

ProcessWindowFunction

全量计算,窗口数据到齐后才计算,容易出现内存溢出。在大量的数据情况下单独使用不合适。可以搭配上面两个增量计算一起使用。他的优势在于能拿到窗口相关的信息。
测试用例:

package com.realtime.flink.function

import com.realtime.flink.dto.OrderDto
import com.realtime.flink.source.OrderSource
import org.apache.flink.api.common.functions.AggregateFunction
import org.apache.flink.streaming.api.scala.function.ProcessAllWindowFunction
import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment, _}
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector

/**
 * 全量计算,窗口数据到齐后才计算,容易出现内存溢出。在大量的数据情况下单独使用不合适
 * 优势:context中有window和windowState
 */
object ProcessFunctionTest  {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.getConfig.setParallelism(1)

    env.addSource(new OrderSource)
      .windowAll(TumblingProcessingTimeWindows.of(Time.seconds(10)))
      .process(new ProcessAllWindowFunction[OrderDto,Double,TimeWindow] {
        override def process(context: Context, elements: Iterable[OrderDto], out: Collector[Double]): Unit = {
          println("当前最大时间窗口:"+context.window.maxTimestamp())
          val ite = elements.iterator
          var result = 0.0
          while (ite.hasNext){
            result = result+ite.next().getOrderPrice
          }
          out.collect(result)
        }
      })
      .print()

    env.execute("tttt")
  }

}

结果:

AAAAAAAAAAA数据:2021-03-30 23:41:04-->9
AAAAAAAAAAA数据:2021-03-30 23:41:05-->2
AAAAAAAAAAA数据:2021-03-30 23:41:06-->2
AAAAAAAAAAA数据:2021-03-30 23:41:07-->9
AAAAAAAAAAA数据:2021-03-30 23:41:08-->1
AAAAAAAAAAA数据:2021-03-30 23:41:09-->2
当前最大时间窗口:1617118869999
25.0
AAAAAAAAAAA数据:2021-03-30 23:41:10-->6
AAAAAAAAAAA数据:2021-03-30 23:41:11-->6
AAAAAAAAAAA数据:2021-03-30 23:41:12-->7
AAAAAAAAAAA数据:2021-03-30 23:41:13-->4
AAAAAAAAAAA数据:2021-03-30 23:41:14-->0
AAAAAAAAAAA数据:2021-03-30 23:41:15-->2
AAAAAAAAAAA数据:2021-03-30 23:41:16-->6
AAAAAAAAAAA数据:2021-03-30 23:41:17-->6
AAAAAAAAAAA数据:2021-03-30 23:41:18-->6
AAAAAAAAAAA数据:2021-03-30 23:41:19-->1
当前最大时间窗口:1617118879999
44.0
AAAAAAAAAAA数据:2021-03-30 23:41:20-->2
AAAAAAAAAAA数据:2021-03-30 23:41:21-->6
AAAAAAAAAAA数据:2021-03-30 23:41:22-->0

总结

本文比较简单介绍了三个窗口函数的使用。后面文章会接着讲解下 windowstate使用以及增量全量窗口函数的配合使用~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值