Flink窗口理解

Windows(窗口分类)
Keyed Stream和Non-Keyed Stream
代码定义上唯一的区别是Keyed Stream以keyBy()开始,后接window(),而Non-Keyed Stream以windowAll()开始,且windowAll是单slot运行的。
Keyed Window

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/apply()      <-  required: "function"
      [.getSideOutput(...)]      <-  optional: "output tag"

Non-Keyed Windows

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/apply()      <-  required: "function"
      [.getSideOutput(...)]      <-  optional: "output tag"

Window Lifecycle(窗口生命周期)
窗口在属于这个窗口的第一条数据到达时创建,在“事件时间或者处理时间 + 用户自定义的允许的延迟时间”到达时移除。
Flink只会移除基于时间的窗口,而不会移除诸如global的窗口。
例如,一个基于事件时间的5分钟滚动窗口,允许时间延迟是1分钟。当12:00的第一条数据到达时,flink会创建一个时间在12:00~12:05的新窗口,这个窗口会在12:06分被移除掉。
另外,每个窗口都会被绑定一个Trigger和一个function (ProcessWindowFunction, ReduceFunction, or AggregateFunction)。这个function包含这个窗口中数据的计算逻辑,而这个Trigger指定了这个窗口中函数被执行的条件。一个trigger策略可能像是“当这个窗口中的元素到达多于4个”,或者“当水位线超过了窗口的截止时间”。一个Trigger也可以决定在窗口存活期任意时间内清除里面的数据,这个例子中清除仅仅是指清除这个窗口内的数据,而不是窗口的元数据。这就意味着新数据仍然可以加入到这个窗口中。
除了上面说的这些,你还可以指定一个Evictor用来在触发器触发后,或者在函数执行前后,从这个window中删除数据。
在Keyed Stream中,你的输入事件中的任何属性(字段)都可以被用来当做key。Keyed Stream能让你的窗口计算被多个task并行执行,因为每个逻辑上的keyed stream都可以被单独处理,同一个key的所有数据会被发送到同一个task去处理。
在Non-Keyed Stream中,你的输入数据不会被拆分成多个流,并且所有的窗口逻辑都会被一个任务处理,也就是说并行度为1.

Window Assigner
指定了你的数据流是Keyed或者Non-Keyed后,下一步是定义WindowAssigner。WindowAssigner定义了数据是如何指定到窗口的。WindowAssigner通过window()(Keyed)或者windowAll()(Non-Keyed)来定义。
一个WindowAssigner负责指定每个输入流数据到一个或者多个窗口。Flink有4中最通用的WindowAssigner类型,滚动窗口(tumbling windows),滑动窗口(sliding windows),会话窗口(session windows)和全局窗口(global windows)。你也可以通过扩展WindowAssigner类来自定义窗口类型。所有的内置WindowAssigner(全局窗口除外)都是基于事件时间或者处理时间指定数据位于哪个窗口的。
基于时间的窗口都有一个开始时间和一个结束时间来描述窗口的大小。在写代码时,当使用基于时间的窗口时,flink用可以查询开始时间戳,结束时间戳或者最大时间戳的方法(返回窗口内最大允许的时间戳)的TimeWindow。
接下来我们展示一下flink的预定义窗口是如何工作的,并且他们在数据流程序中是如何使用的。接下来的图表将可视化的展现每个WindowAssigner的工作机制。紫色的圆圈代表数据流中的数据,这些数据被某些key(user1, user2, user3)分区了。X轴代表处理时间。

Tumbling Windows(滚动窗口)
滚动窗口指定每个数据到一个特定大小的窗口内。滚动窗口有固定的大小并且不会重合。例如,如果你指定了一个5分钟的滚动窗口,每5分钟前一个窗口会被计算并且开启另一个新的窗口接收新数据。如下图所示
在这里插入图片描述
下面的代码展示如何使用滚动窗口

DataStream<T> input = ...;

// tumbling event-time windows
input
    .keyBy(<key selector>)
    .window(TumblingEventTimeWindows.of(Time.seconds(5)))
    .<windowed transformation>(<window function>);

// tumbling processing-time windows
input
    .keyBy(<key selector>)
    .window(TumblingProcessingTimeWindows.of(Time.seconds(5)))
    .<windowed transformation>(<window function>);

// daily tumbling event-time windows offset by -8 hours.
input
    .keyBy(<key selector>)
    .window(TumblingEventTimeWindows.of(Time.days(1), Time.hours(-8)))
    .<windowed transformation>(<window function>);

时间间隔可以用 Time.milliseconds(x), Time.seconds(x), Time.minutes(x) 等等中的一个去指定。
在上面的例子中,滚动窗口也可以使用可选offset参数,用来改变窗口的对齐时间。例如,没有offset,小时滚动窗口按整点对齐,你将会拿到诸如1:00:00.000 - 1:59:59.999, 2:00:00.000 - 2:59:59.999这样的窗口。如果你想修改,你可以给定一个offset。例如你想要一个由15分钟offset的窗口,那你将会拿到诸如1:15:00.000 - 2:14:59.999, 2:15:00.000 - 3:14:59.999这样的时间窗口。一个offset重要的使用案例是调整时区,比如在中国,你要设置offset Time.hours(-8)。

Sliding Windows(滑动窗口)
滑动窗口将数据指定到大小固定的窗口。和滚动窗口相似,窗口的大小通过窗口参数配置。另外一个滑动窗口参数控制窗口触发的频率。因此,如果滑动的尺寸小于整个窗口尺寸,滑动窗口之间可能会重合。在这种情况下,数据会被分配到多个不同的窗口。
例如,你可以设置一个10分钟大小的窗口,每5分钟滑动一次。这样你可以每5分钟拿到一个包含前面10分钟数据的窗口。如下图所示
在这里插入图片描述
下面的java代码展示如何使用滑动窗口

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值