学习 Flink(三):窗口

更新至 Flink 1.9.0 版本

窗口类型

滚动窗口

滚动窗口(Tumbling Window)又称固定窗口(Fixed Window),将时间分配到固定大小且非重叠的桶中。当超过了窗口边界,事件就会发送到执行函数进行处理。

计数滚动窗口基于计数的滚动窗口,定义了在出发执行之前需要收集多少事件:

Count-based Tumbling Window

ds.keyBy(0)  
  .countWindow(4) // ①
  .sum(1)
  .print()

① 计数为 4 的窗口

时间滚动窗口基于时间的滚动窗口,定义了事件缓存在桶中的时间周期。

Time-based Tumbling Window

ds.keyBy(0)  
  .timeWindow(Time.minutes(10)) // ①
  .sum(1)
  .print()

① 时间为 10 分钟的窗口

滑动窗口

滑动窗口(Sliding Window)将事件分配到固定大小且重叠的桶中。因此,事件有可能属于多个桶。滑动窗口由长度和滑动(Slide)定义。

Count-based Sliding Window

ds.keyBy(0)  
  .countWindow(4, 3) // ①
  .sum(1)
  .print()

① 计数为 4 滑动为 3 的窗口

会话窗口

会话窗口(Session Window)中的会话为间隔时间小于会话间隔(Session Gap)的事件。

Session Window

ds.keyBy(0)  
  .window(ProcessingTimeSessionWindows.withGap(Time.minutes(5))) // ①
  .sum(1)
  .print()

① 间隔小于 5 分钟为一个 Session 的窗口

窗口函数

Flink 支持以下窗口函数:

  • org.apache.flink.api.common.functions.ReduceFunction
  • org.apache.flink.api.common.functions.AggregateFunction
  • org.apache.flink.api.common.functions.FoldFunction
  • org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction

同时支持 ProcessWindowFunction 和 ReduceFuntion、AggregateFunction、FoldFunction 之一组合,实现增量聚合,减少 ProcessWindowFunction 处理的数据量。

在 ProcessWindowFunction 通过 process(KEY key, Context context, Iterable<IN> elements, Collector<OUT> out):void 方法的 Context 对象获取窗口状态。

globalState() 访问不限制窗口的键状态。如下图 user X 对应的全局状态;

windowState() 访问限制窗口的键状态。如下图 user X 对应的具体窗口的状态。

Per-window State

窗口实现

窗口的本质就是将数据流中的一组事件放入一个有界的桶中。窗口执行,可以是时间驱动,也可以是数据驱动。

窗口的三个组件:

  • Window Assigner 用于将零到多个窗口分配给事件;
  • Trigger 决定了何时触发窗口执行;
  • Evictor 在 WindowFunction 执行之前和之后移除窗口事件。

Window Assigner

Window Assigner 继承自 org.apache.flink.streaming.api.windowing.assigners 抽象类。

Window Assygner

Trigger

Trigger 继承自 org.apache.flink.streaming.api.windowing.triggers.Trigger 抽象类。

Trigger

Evictor

Evictor 继承自 org.apache.flink.streaming.api.windowing.evictors.Evictor 接口。

Evictor

参考: