基于本文回答
0
评论

FlinkSQL 中的窗口类型

在 Flink SQL 中,窗口(Windows)是处理无界数据流(Streaming)的核心机制。它将无界的数据流切分成有限大小的“桶”(buckets),并在这些桶上进行聚合计算(如 SUM、AVG 等)。

从 Flink 1.13 开始,官方推荐使用 窗口表值函数(Windowing TVFs, Window Table-Valued Functions) 来定义窗口,它比老版本的 Group Window 功能更强大、性能更好,且更符合 SQL 标准。

以下是 Flink SQL 中最主要的几种窗口类型及其详细介绍:


1. 滚动窗口 (Tumble Windows)

特点

  • 大小固定,窗口之间不重叠,也没有间隙。
  • 每个元素只属于一个窗口。

适用场景

  • 计算每分钟的 PV/UV。
  • 计算每小时的销售总额。

Flink SQL 语法 (TVF)

sql
SELECT window_start, window_end, SUM(price)
FROM TABLE(
  TUMBLE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES)
)
GROUP BY window_start, window_end;
  • bidtime:时间属性列(Event Time 或 Processing Time)。
  • INTERVAL '10' MINUTES:窗口大小(10分钟)。

2. 滑动窗口 (Hop Windows / Sliding Windows)

特点

  • 大小固定,但窗口之间有重叠
  • 由两个参数定义:窗口大小 (Size)滑动步长 (Slide)
  • 一个元素可能会被分配到多个窗口中。

适用场景

  • 每隔 5 分钟,计算过去 1 小时内的活跃用户数(Size = 1小时, Slide = 5分钟)。
  • 监控最近 10 分钟内的异常报错频率。

Flink SQL 语法 (TVF)

sql
SELECT window_start, window_end, SUM(price)
FROM TABLE(
  HOP(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES, INTERVAL '1' HOURS)
)
GROUP BY window_start, window_end;
  • INTERVAL '5' MINUTES:滑动步长(Slide)。
  • INTERVAL '1' HOURS:窗口大小(Size)。

3. 累积窗口 (Cumulate Windows)

特点

  • 在指定的最大窗口长度内,按照步长定期触发计算,并累积之前的数据。
  • 简单来说,它是“固定起点,动态终点”的窗口。

适用场景

  • 天级累计指标:从每天 00:00 开始,每隔 10 分钟计算一次当天截止到当前时间的累计 GMV(最大长度 24 小时,步长 10 分钟)。

Flink SQL 语法 (TVF)

sql
SELECT window_start, window_end, SUM(price)
FROM TABLE(
  CUMULATE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES, INTERVAL '1' DAYS)
)
GROUP BY window_start, window_end;
  • INTERVAL '10' MINUTES:累积的步长(每10分钟触发并更新一次结果)。
  • INTERVAL '1' DAYS:最大窗口大小(一天结束时窗口重置)。

4. 会话窗口 (Session Windows)

特点

  • 通过间隙时间 (Gap) 来切分窗口。如果一段时间内没有数据流入(超过了 Gap 长度),则当前的窗口关闭,新来的数据将开启一个新窗口。
  • 窗口的长度是动态的,且每个 Key 的窗口边界可能不同。

适用场景

  • 用户行为分析:计算用户一次“活跃会话(Session)”内的点击次数(如果用户超过 30 分钟未操作,则认为会话结束)。

Flink SQL 语法 (TVF)
(注意:Session Window TVF 在 Flink 1.14+ 中引入)

sql
SELECT window_start, window_end, count(1)
FROM TABLE(
  SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '30' MINUTES)
)
GROUP BY window_start, window_end, user_id;
  • INTERVAL '30' MINUTES:会话不活跃的超时时间(Gap)。

5. 渐变窗口 / 聚合窗口 (Over Windows)

特点

  • 与传统的 Group Window(将数据划分到不同的桶)不同,Over 窗口是针对每一条数据,计算其对应的一个窗口范围(类似于传统数据库的窗口函数 OVER (PARTITION BY ... ORDER BY ...))。
  • 每一条数据都会触发一次计算。

适用场景

  • 计算当前行与前 10 行数据的平均值。
  • 计算当前用户最近 1 小时内的累计消费金额(每来一笔算一次)。

Flink SQL 语法

sql
SELECT order_id, order_time, amount,
  SUM(amount) OVER (
    PARTITION BY user_id
    ORDER BY order_time
    RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW
  ) as one_hour_sum
FROM Orders;
  • 支持基于时间范围RANGE BETWEEN...)和基于行数ROWS BETWEEN...)的定义。

总结与对比

窗口类型 窗口大小 窗口是否重叠 触发频率 典型应用场景
Tumble (滚动) 固定 窗口结束时一次性触发 统计每小时/每天的独立指标
Hop (滑动) 固定 每隔 Slide 时间触发一次 统计最近 N 分钟/小时的滑动指标
Cumulate (累积) 动态增长 是(包含关系) 每隔 Step 时间触发,累积数据 天级累计 GMV、累计 UV
Session (会话) 动态 超过 Gap 时间无数据时触发 用户单次访问会话分析
Over (渐变) 动态 每条数据流入都触发 实时滚动均值、最新 N 条数据聚合

最佳实践建议
在 Flink 1.13 及以上版本中,编写 Flink SQL 时应优先使用 Window TVF 语法(即 SELECT * FROM TABLE(TUMBLE(...))),因为 TVF 支持性能优化(如 Local-Global 聚合)Window Join 以及 Window Top-N 等高级功能。

右滑查看面试常问