基于本文回答
0
评论

Flink 中的 Window 分为哪几类?

知识点图片

在 Apache Flink 中,Window(窗口)是将无限流(Unbounded Stream)切割为有限流(Bounded Stream)的核心机制。

Flink 的窗口分类通常可以从以下 三个维度 进行划分:


1. 按照窗口分配器 (Window Assigner) 分类 —— 最核心的分类

这是最常被问到的分类方式,它决定了数据如何被分配到不同的窗口中。主要分为以下四类:

A. 滚动窗口 (Tumbling Windows)

  • 特点:窗口大小固定,窗口之间不重叠,且首尾相接。
  • 适用场景:每个数据只属于一个窗口。例如:每 5 分钟统计一次 PV。
  • APITumblingEventTimeWindows, TumblingProcessingTimeWindows

B. 滑动窗口 (Sliding Windows)

  • 特点:窗口大小固定,但窗口之间有重叠。由 Window Size(窗口大小)和 Window Slide(滑动步长)两个参数决定。
  • 适用场景:需要对最近一段时间内的数据进行频率统计。例如:每 1 分钟统计过去 5 分钟的平均值。
  • APISlidingEventTimeWindows, SlidingProcessingTimeWindows

C. 会话窗口 (Session Windows)

  • 特点:窗口大小不固定。它由“会话间隙”(Session Gap)决定,即如果一段时间内没有接收到新数据,则认为当前会话结束,窗口关闭。
  • 适用场景:用户行为分析。例如:统计用户在一个连续活跃期间的操作,如果用户 30 分钟没操作,则视为新会话。
  • APIEventTimeSessionWindows, ProcessingTimeSessionWindows

D. 全局窗口 (Global Windows)

  • 特点:将所有相同 Key 的数据分配到同一个巨大的窗口中。这个窗口默认没有结束时间。
  • 注意:Global Window 必须配合自定义的 Trigger(触发器) 使用,否则窗口永远不会触发计算(因为默认 Trigger 是 NeverTrigger)。
  • 适用场景:需要自定义复杂的触发逻辑(如:每攒够 1000 条数据计算一次,或者遇到特定结束标志才计算)。
  • APIGlobalWindows

2. 按照驱动类型 (Time vs Count) 分类

窗口的触发和划分是基于“时间”还是“数量”?

A. 时间窗口 (Time Window)

  • 基于时间范围划分。
  • 又细分为:
    • Event Time (事件时间):基于数据自带的时间戳。
    • Processing Time (处理时间):基于机器系统时间。

B. 计数窗口 (Count Window)

  • 基于元素的个数划分。
  • 滚动计数窗口:例如每 100 个元素计算一次。
  • 滑动计数窗口:例如每收到 10 个元素,计算过去 100 个元素。
  • 注:底层其实是 Global Window + CountTrigger 实现的。

3. 按照数据流类型 (Keyed vs Non-Keyed) 分类

这决定了窗口是在并发流上运行,还是在单线程流上运行。

A. Keyed Windows (键控窗口)

  • 定义:在 keyBy() 操作之后调用的窗口。
  • 特点stream.keyBy(...).window(...)
  • 并发性:高。不同 Key 的窗口会分布在不同的 Task Slot 中并行计算。

B. Non-Keyed Windows (非键控窗口)

  • 定义:直接在 DataStream 上调用 windowAll()
  • 特点stream.windowAll(...)
  • 并发性并行度强制为 1。所有数据都会汇聚到一个 Task 中处理,容易成为性能瓶颈(Data Skew)。

总结图表

维度 类别 描述 典型 API
分配逻辑 滚动 (Tumbling) 固定大小,无重叠 .window(TumblingEventTimeWindows.of(...))
滑动 (Sliding) 固定大小,有重叠 .window(SlidingEventTimeWindows.of(...))
会话 (Session) 动态大小,基于间隙 .window(EventTimeSessionWindows.withGap(...))
全局 (Global) 单一无限大窗口 .window(GlobalWindows.create())
驱动方式 时间 (Time) 基于事件或处理时间 (上述 API 均支持)
计数 (Count) 基于条数 .countWindow(size) / .countWindow(size, slide)
数据流向 Keyed 并行处理 .keyBy(...).window(...)
Non-Keyed 单点全量处理 .windowAll(...)
右滑查看面试常问