在 Apache Flink 中,窗口(Window) 是将无界数据流划分为有限块进行处理的核心机制,主要用于聚合(如 sum、avg、count)或复杂事件处理。Flink 提供了丰富的窗口类型,主要分为两大类:
一、按驱动方式分类(Keyed Stream 使用)
1. 时间窗口(Time Windows)
-
滚动时间窗口 (Tumbling Time Windows)
- 固定长度、不重叠的窗口。
- 示例:每5分钟统计一次销售额。
- 代码:
.window(TumblingEventTimeWindows.of(Time.minutes(5)))
-
滑动时间窗口 (Sliding Time Windows)
- 固定长度、可重叠的窗口(需指定窗口大小和滑动步长)。
- 示例:每1分钟输出过去5分钟内的访问量。
- 代码:
.window(SlidingEventTimeWindows.of(Time.minutes(5), Time.minutes(1)))
-
会话窗口 (Session Windows)
- 动态长度,根据数据活跃度划分(不活跃间隔触发关闭)。
- 示例:用户连续操作间隔超过10分钟则关闭会话。
- 代码:
.window(EventTimeSessionWindows.withGap(Time.minutes(10)))
2. 计数窗口(Count Windows)
-
滚动计数窗口 (Tumbling Count Windows)
- 固定元素数量、不重叠。
- 示例:每100个点击事件统计一次。
- 代码:
.countWindow(100)
-
滑动计数窗口 (Sliding Count Windows)
- 固定元素数量、可重叠(需指定窗口大小和滑动步长)。
- 示例:每50个新事件触发一次最近100个事件的统计。
- 代码:
.countWindow(100, 50)
二、特殊窗口类型
1. 全局窗口(Global Window)
- 将所有数据分配到单个窗口,需自定义触发器(Trigger)决定何时计算。
- 适用于自定义窗口逻辑(如基于业务规则触发)。
- 代码:
.window(GlobalWindows.create())
2. 增量聚合窗口(通过 reduce() / aggregate() 优化)
- 使用
ReduceFunction或AggregateFunction在窗口内增量计算,降低状态开销。 - 示例:实时更新每分钟的销售额总和。
- 代码:
.window(...).reduce(new MyReduceFunction())
3. ProcessFunction 底层窗口(非 Keyed 流)
- 通过
ProcessFunction或KeyedProcessFunction手动管理时间与状态,实现完全自定义窗口逻辑。
三、窗口分配器(Window Assigners)
创建窗口时需指定分配器,常见类型包括:
TumblingEventTimeWindows/TumblingProcessingTimeWindowsSlidingEventTimeWindows/SlidingProcessingTimeWindowsEventTimeSessionWindows/ProcessingTimeSessionWindowsGlobalWindows
四、窗口函数(Window Functions)
窗口分配后,需定义计算逻辑:
- 全量窗口函数
ProcessWindowFunction:访问窗口内全量数据及元信息(如窗口起止时间)。
- 增量聚合函数
ReduceFunction/AggregateFunction:逐条处理数据,高效但无法访问元信息。
- 组合使用
- 增量聚合 +
ProcessWindowFunction:兼顾效率与元信息访问(推荐)。
- 增量聚合 +
选择窗口的关键点
- 时间语义:根据业务选择
Event Time(事件时间)或Processing Time(处理时间)。 - 数据特征:
- 固定周期统计 → 滚动窗口。
- 平滑移动统计 → 滑动窗口。
- 用户行为分段 → 会话窗口。
- 性能需求:优先使用增量聚合(
reduce/aggregate)。
示例代码(事件时间滚动窗口)
DataStream<T> stream = ...;
stream
.keyBy(<key selector>)
.window(TumblingEventTimeWindows.of(Time.seconds(30))) // 30秒滚动窗口
.reduce(new MyReduceFunction()); // 增量聚合
掌握这些窗口类型后,可灵活应对实时计算的各类场景(如监控、风控、报表等)。如需深入某个窗口的细节或触发器(Trigger)、驱逐器(Evictor)等高级用法,可进一步探讨!
366

被折叠的 条评论
为什么被折叠?



