首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从零开始学Flink:Flink SQL 窗口(Window)操作详解

从零开始学Flink:Flink SQL 窗口(Window)操作详解

原创
作者头像
用户4160816
发布2026-02-09 14:41:10
发布2026-02-09 14:41:10
110
举报
文章被收录于专栏:从零开始学Flink从零开始学Flink

在上一篇 Flink SQL 极简入门 中,我们体验了 Flink SQL 的基础用法。但在流处理中,最核心、最迷人(也最让人头秃)的概念莫过于“时间”“窗口(Window)”

你可能经常听到这样的业务需求:

  • “每 5 分钟统计一次订单总量”
  • “实时统计过去 1 小时内的热门商品,每 10 秒更新一次”
  • “每天 0 点到当前时刻的累计 PV”

这些需求都离不开窗口。今天,我们就来深入 Flink SQL 的窗口机制,看看它是如何驯服无限数据流的。

什么是窗口 (Window)?

流数据(Stream)是无限的,像水流一样源源不断。我们无法计算“无限流”的总和(因为永远算不完)。为了计算,我们需要把无限的流“切”成有限的块,这个“切”的操作就是开窗(Windowing)

在 Flink SQL 中,窗口主要用于将时间序列上的数据分桶,然后在桶内进行聚合计算(如 SUM, COUNT, AVG)。

新一代标准:Window TVF

在 Flink 1.13 之前,我们主要使用 GROUP WINDOW(如 TUMBLE(rowtime, ...) 在 GROUP BY 子句中)。但从 Flink 1.13 开始,官方推荐使用 Window TVF (Table-Valued Functions)

Window TVF 符合 SQL 2016 标准,语法更自然,功能更强大(支持 TopN、去重等复杂操作)。本文将以 Window TVF 为主进行讲解。

核心语法结构通常如下:

代码语言:sql
复制
SELECT window_start, window_end, SUM(price)
FROM TABLE(
-- 窗口函数
TUMBLE(TABLE my_table, DESCRIPTOR(ts), INTERVAL '5' MINUTE)
)
GROUP BY window_start, window_end;

三大核心窗口类型

1. 滚动窗口 (Tumble Window)

特点:窗口大小固定,窗口之间不重叠,首尾相接。

场景:每隔 5 分钟统计一次。

Tumble Window
Tumble Window

语法

TUMBLE(TABLE data, DESCRIPTOR(time_col), INTERVAL '10' MINUTE)

2. 滑动窗口 (Hop Window)

特点:窗口大小固定,但窗口之间可以重叠。它有两个参数:

  1. Window Size (窗口大小):统计多长时间的数据(如“过去 1 小时”)。
  2. Window Slide (滑动步长):多久更新一次结果(如“每 5 分钟”)。

场景:每 5 分钟,统计过去 1 小时的 PV。

Hop Window
Hop Window

语法

HOP(TABLE data, DESCRIPTOR(time_col), INTERVAL '5' MINUTE, INTERVAL '1' HOUR)

注意:参数顺序是先 Slide (步长),后 Size (大小)。

3. 累积窗口 (Cumulate Window)

特点:这是 Flink 特有的窗口,用于解决“每天 0 点至今的累计值”这类需求。它会按步长输出一个个不断变大的窗口,直到达到最大窗口大小。

场景:每天的实时累计销售额(每 10 分钟更新一次看到当天的累计值)。

Cumulate Window
Cumulate Window

语法

CUMULATE(TABLE data, DESCRIPTOR(time_col), INTERVAL '10' MINUTE, INTERVAL '1' DAY)


实战:处理“过去 5 分钟的订单总额”

让我们回到开头的经典需求。假设我们有一个订单流 orders

0. 准备数据环境

首先,我们启动 SQL Client

代码语言:bash
复制
./bin/sql-client.sh

创建一个模拟的订单源表(使用 DataGen 连接器):

代码语言:sql
复制
CREATE TABLE orders (
order_id INT,
price DOUBLE,
order_time TIMESTAMP(3),
-- 定义水位线,基于 order_time,延迟 0 秒
WATERMARK FOR order_time AS order_time - INTERVAL '0' SECOND
) WITH (
'connector' = 'datagen',
'rows-per-second' = '1',
'fields.price.min' = '10',
'fields.price.max' = '100'
);

需求一:每 5 分钟,统计该 5 分钟内的订单总额

这是一个典型的滚动窗口 (Tumble)。比如 12:00-12:05 一个结果,12:05-12:10 一个结果。

代码语言:sql
复制
SELECT 
window_start, 
window_end, 
COUNT(*) as total_orders, 
SUM(price) as total_amount
FROM TABLE(
TUMBLE(TABLE orders, DESCRIPTOR(order_time), INTERVAL '5' MINUTE)
)
GROUP BY window_start, window_end;

运行结果示例

5分钟内订单总额
5分钟内订单总额

需求二:实时统计“过去 5 分钟”的订单总额,每 1 分钟更新一次

这是一个典型的滑动窗口 (Hop)

  • 窗口大小:5 分钟
  • 滑动步长:1 分钟

这样,12:00 输出 11:55, 12:00 的数据;12:01 输出 11:56, 12:01 的数据。

代码语言:sql
复制
SELECT 
window_start, 
window_end, 
SUM(price) as total_amount
FROM TABLE(
HOP(TABLE orders, DESCRIPTOR(order_time), INTERVAL '1' MINUTE, INTERVAL '5' MINUTE)
)
GROUP BY window_start, window_end;

运行结果示例

过去5分钟订单总额
过去5分钟订单总额

注意

HOP 函数的参数中,第一个时间是滑动步长 (Slide)第二个时间是窗口大小 (Size)。千万别搞反了!

INTERVAL '1' MINUTE = Slide (更新频率)

INTERVAL '5' MINUTE = Size (统计范围)

总结

Flink SQL 的 Window TVF 极大地简化了窗口聚合的写法。

  • TUMBLE: 规规矩矩,互不干扰(分批统计)。
  • HOP: 藕断丝连,频繁更新(移动平均/最近 N 分钟)。
  • CUMULATE: 聚沙成塔,越积越多(日报/大屏累计)。

掌握了这三种窗口,你就能覆盖 90% 的实时统计需求了。

下一篇,我们将挑战更复杂的场景:双流 JOIN,看看当“订单流”遇到“用户流”,Flink 该如何处理?


原文来自

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是窗口 (Window)?
  • 新一代标准:Window TVF
  • 三大核心窗口类型
    • 1. 滚动窗口 (Tumble Window)
    • 2. 滑动窗口 (Hop Window)
    • 3. 累积窗口 (Cumulate Window)
  • 实战:处理“过去 5 分钟的订单总额”
    • 0. 准备数据环境
    • 需求一:每 5 分钟,统计该 5 分钟内的订单总额
    • 需求二:实时统计“过去 5 分钟”的订单总额,每 1 分钟更新一次
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档