Flink 窗口与时间语义速记手册
一、窗口概念
1. 为什么需要窗口?
- 流数据是无限的,但业务分析通常要聚合有限的数据片段。
- 窗口机制将无限流切分为有限“小流”,便于统计、聚合和分析(如每分钟订单总额)。
2. 窗口分类
- 时间窗口:按时间段分割(如每5秒一个窗口)。
- 计数窗口:按数据条数分割(如每100条一个窗口)。
- 会话窗口:按事件间隔分割(如用户10分钟无操作即分割)。
二、常见窗口类型
1. 翻滚窗口(Tumbling Window)
- 特点:窗口长度固定,窗口间无重叠。
- 应用:每5秒统计一次PV。
- 代码示例:
stream .keyBy(x -> x.userId) .window(TumblingEventTimeWindows.of(Time.seconds(5))) .sum("amount");
2. 滑动窗口(Sliding Window)
- 特点:窗口长度固定,可重叠。窗口有“长度”和“滑动步长”。
- 应用:每10秒统计最近5秒的数据。
- 代码示例:
stream .keyBy(x -> x.userId) .window(SlidingEventTimeWindows.of(Time.seconds(10), Time.seconds(5))) .sum("amount");
3. 会话窗口(Session Window)
- 特点:根据一段“静默”时间自动分割窗口(如30分钟无事件)。
- 应用:用户行为分析、会话统计。
- 代码示例:
stream .keyBy(x -> x.userId) .window(ProcessingTimeSessionWindows.withGap(Time.minutes(30))) .sum("amount");
4. 全局窗口(Global Window)
- 特点:只有一个窗口,需自定义触发器才能输出结果。
- 代码示例:
stream .keyBy(x -> x.userId) .window(GlobalWindows.create()) .trigger(...)
三、窗口API用法
- 窗口分配:
.window(WindowAssigner)
- 计数窗口:
.countWindow(size, slide)
- 窗口函数:
.reduce(ReduceFunction)
.aggregate(AggregateFunction)
.process(ProcessWindowFunction)
- 代码示例:
stream .keyBy(...) .window(...) .reduce(new MyReduceFunction());
四、窗口函数详解
- ReduceFunction:两两合并,适合sum、min等。
- AggregateFunction:支持不同输入/输出类型,增量计算。
- ProcessWindowFunction:可获取窗口元数据,功能最强大。
- 组合用法(更高效):
stream .keyBy(...) .window(...) .aggregate(new MyAggFunc(), new MyProcessWindowFunc());
五、自定义窗口与高级用法
- 自定义窗口分配器:继承
WindowAssigner
实现特殊分割规则。 - 窗口触发器(Trigger):决定窗口何时输出结果(如时间、条数、条件等)。
- 窗口清理器(Evictor):窗口计算前后剔除部分元素,减少资源消耗。
六、Flink时间语义与Watermark
1. 时间语义
- Processing Time:Flink处理数据的本地时间,延迟低但不准。
- Event Time:事件自带时间戳,配合Watermark,最准确。
- Ingestion Time:数据进入Flink的时间。
2. Watermark机制
- Watermark:水位线,标记“到达”的最大事件时间,决定窗口何时触发。
- 常用Watermark策略(允许乱序5秒):
stream.assignTimestampsAndWatermarks( WatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ofSeconds(5)) .withTimestampAssigner((event, ts) -> event.getTimestamp()) );
3. 乱序与迟到数据
- 允许乱序:设置最大乱序时间,保证窗口完整性。
- 迟到数据处理:
allowedLateness
、sideOutputLateData
输出迟到数据。
七、窗口案例
- 每分钟订单总额统计:翻滚窗口 + ReduceFunction。
- 用户会话内点击数:会话窗口 + AggregateFunction。
- 实时TopN统计:滑动窗口 + ProcessWindowFunction。
八、总结
Flink窗口机制让流式数据处理变得灵活高效,配合多样的窗口类型、时间语义和Watermark机制,可以应对绝大多数实时分析场景。掌握窗口API和时间语义,是Flink开发的必备基础。
欢迎收藏,随查随用!如需具体案例代码或进阶用法,欢迎留言交流。