窗口机制:四种窗口一次讲透
滚动窗口 · 滑动窗口 · 会话窗口 · 全局窗口 · 触发器
📋 面试题
Flink有哪几种窗口?分别适用于什么场景?窗口是怎么触发计算的?
💡 先想30秒,再往下看答案
为什么需要窗口?
流数据是无限的,不可能等所有数据到齐再算。窗口的作用就是把无限流切成有限的块,在每个块上做聚合计算。
四种窗口对比
| 窗口类型 | 特点 | 典型场景 |
|---|---|---|
| 滚动窗口 | 固定大小、不重叠 | 每分钟PV、每小时GMV |
| 滑动窗口 | 固定大小、有重叠 | 最近5分钟的平均值,每1分钟更新 |
| 会话窗口 | 按活跃间隔划分、大小不固定 | 用户会话分析 |
| 全局窗口 | 所有数据在一个窗口 | 自定义触发逻辑 |
滚动窗口(最常用)
|----窗口1----|----窗口2----|----窗口3----|
00:00 00:05 00:10 00:15
特点:窗口之间不重叠,每条数据只属于一个窗口
// 5分钟滚动窗口
stream.keyBy(e -> e.userId)
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
.sum("amount");
滑动窗口
|--------窗口1--------|
|--------窗口2--------|
|--------窗口3--------|
00:00 00:01 00:02 00:03 00:04 00:05
窗口大小5分钟,滑动步长1分钟
特点:窗口有重叠,一条数据可能属于多个窗口
// 窗口大小5分钟,每1分钟滑动一次
stream.keyBy(e -> e.userId)
.window(SlidingEventTimeWindows.of(Time.minutes(5), Time.minutes(1)))
.sum("amount");
💡 滑动窗口的坑:窗口大小/滑动步长 = 数据膨胀倍数。5分钟窗口每1分钟滑动,每条数据被复制5份。我见过有人设了1小时窗口每1秒滑动,数据膨胀3600倍直接OOM。
会话窗口
|--会话1--| |-----会话2-----| |--会话3--|
活跃 Gap>阈值 活跃 活跃 Gap>阈值 活跃
特点:窗口大小不固定,由数据的活跃间隔决定
// 30秒无活动则关闭会话窗口
stream.keyBy(e -> e.userId)
.window(EventTimeSessionWindows.withGap(Time.seconds(30)))
.aggregate(new SessionAggFunction());
窗口触发机制
窗口什么时候触发计算?核心逻辑:
Event Time窗口:Watermark >= 窗口结束时间 → 触发
Processing Time窗口:机器时间 >= 窗口结束时间 → 触发
具体过程:
窗口 [10:00, 10:05)
↓
数据陆续到达,放入窗口
↓
Watermark推进到 10:05
↓
触发窗口计算 → 输出结果
↓
窗口销毁(默认)
窗口函数的选择
| 函数 | 特点 | 适用场景 |
|---|---|---|
| ReduceFunction | 增量计算,内存小 | 简单聚合(sum/count) |
| AggregateFunction | 增量计算,更灵活 | 复杂聚合(平均值/TopN) |
| ProcessWindowFunction | 全量计算,拿到所有数据 | 需要遍历窗口内所有数据 |
| 增量+全量组合 | 先增量聚合,触发时补充窗口信息 | 生产环境最常用 |
// 生产推荐:增量+全量组合
stream.keyBy(...)
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
.aggregate(new MyAggFunction(), new MyProcessWindowFunction());
// MyAggFunction增量计算,最终结果传给ProcessWindowFunction补充窗口元信息
我在实时数仓里全部用的AggregateFunction + ProcessWindowFunction组合。AggregateFunction增量计算不攒数据,ProcessWindowFunction只在触发时拿到聚合结果和窗口信息(开始时间、结束时间),内存友好又功能完整。
面试加分提示
💡 讲清楚三层:类型+触发机制+函数选择
「四种窗口:滚动(不重叠)、滑动(重叠)、会话(按活跃间隔)、全局。生产最常用滚动窗口。Event Time窗口在Watermark到达窗口结束时间时触发。
窗口函数推荐用AggregateFunction + ProcessWindowFunction的组合:前者增量计算节省内存,后者补充窗口元信息。
注意滑动窗口的数据膨胀问题。」
📌 总结
| 记忆点 | 内容 |
|---|---|
| 四种窗口 | 滚动/滑动/会话/全局 |
| 生产首选 | 滚动窗口最常用 |
| 触发条件 | Watermark >= 窗口结束时间 |
| 滑动窗口坑 | 大小/步长=膨胀倍数 |
| 函数推荐 | Aggregate + ProcessWindow组合 |
▶ 下一篇预告:DAY 4 State状态管理
Wood聊大数据 | 9年大数据老兵,聊技术、聊职场、聊成长
小红书正文
Flink四种窗口你都能讲清楚吗?面试经常问完类型就追问触发机制和函数选择。
四种窗口:滚动(固定不重叠)、滑动(固定有重叠)、会话(按活跃间隔)、全局(自定义触发)。生产最常用滚动窗口。
关键细节:Event Time窗口的触发条件是Watermark到达窗口结束时间。
大坑:滑动窗口的数据膨胀。5分钟窗口每1分钟滑动=每条数据复制5份。见过有人1小时窗口每秒滑动,膨胀3600倍直接OOM。
窗口函数生产推荐:AggregateFunction+ProcessWindowFunction组合。增量计算不攒数据,触发时补充窗口元信息。