Window是flink处理无限数据量的核心
官网链接:
https://ci.apache.org/projects/flink/flink-docs-release-1.13/zh/docs/dev/datastream/operators/windows 背景
数据流是一直源源不断产生,业务需要聚合统计使用,比如每10秒统计过去5分钟的点击量、成交额等
Windows 就可以将无限的数据流拆分为有限大小的“桶 buckets”,然后程序可以对其窗口内的数据进行计算
窗口认为是桶,一个窗口段就是一个桶,比如8到9点是一个桶,9到10点是一个桶
分类
time Window 时间窗口,即按照一定的时间规则作为窗口统计
1. time-tumbling-window 时间滚动窗口 (用的多)
2. time-sliding-window 时间滑动窗口 (用的多)
3. session WIndow 会话窗口,即一个会话内的数据进行统计,相对少用
数量窗口:
- count Window 数量窗口,即按照一定的数据量作为窗口统计,相对少用
窗口属性
滚动窗口 Tumbling Windows
窗口具有固定大小
窗口数据不重叠
例子:每10s统计一次最近10s内的订单数量
滑动窗口 Sliding Windows
窗口具有固定大小
窗口数据有重叠
例子:每10s统计一次最近1min内的订单数量
窗口函数总结:
窗口大小size 和 滑动间隔 slide
tumbling-window:滚动窗口: size=slide,如:每隔10s统计最近10s的数据
sliding-window:滑动窗口: size>slide,如:每隔5s统计最近10s的数据
size<slide的时候,如每隔15s统计最近10s的数据,那么中间5s的数据会丢失,所以开发中不用
什么情况下才可以使用WindowAPI
有keyBy 用 window() api
没keyBy 用 windowAll() api ,并行度低
方括号 ([…]) 中的命令是可选的,允许用多种不同的方式自定义窗口逻辑
Keyed Windows
stream
.keyBy(...) <- keyed versus non-keyed windows
.window(...) <- required: "assigner"
[.trigger(...)] <- optional: "trigger" (else default trigger)
[.evictor(...)] <- optional: "evictor" (else no evictor)
[.allowedLateness(...)] <- optional: "lateness" (else zero)
[.sideOutputLateData(...)] <- optional: "output tag" (else no side output for late data)
.reduce/aggregate/apply() <- required: "function"
[.getSideOutput(...)] <- optional: "output tag"
Non-Keyed Windows
stream
.windowAll(...) <- required: "assigner"
[.trigger(...)] <- optional: "trigger" (else default trigger)
[.evictor(...)] <- optional: "evictor" (else no evictor)
[.allowedLateness(...)] <- optional: "lateness" (else zero)
[.sideOutputLateData(...)] <- optional: "output tag" (else no side output for late data)
.reduce/aggregate/apply() <- required: "function"
[.getSideOutput(...)] <- optional: "output tag"
注:
- 一个窗口是左闭右开
- countWindow没过期,但timeWindow在1.12过期,统一使用window;
窗口分配器 Window Assigners
定义了如何将元素分配给窗口,负责将每条数据分发到正确的 window窗口上
window() 的参数是一个 WindowAssigner,flink本身提供了Tumbling、Sliding 等Assigner
窗口触发器 trigger
用来控制一个窗口是否需要被触发
每个 窗口分配器WindowAssigner 都有一个默认触发器,也支持自定义触发器
窗口 window function ,对窗口内的数据做啥?
- 定义了要对窗口中收集的数据做的计算操作
- 增量聚合函数 aggregate(agg函数,WindowFunction(){ })
1.窗口保存临时数据,每进入一个新数据,会与中间数据累加,生成新的中间数据,再保存到窗口中
2.常见的增量聚合函数有 reduceFunction、aggregateFunction
3.min、max、sum 都是简单的聚合操作,不需要自定义规则
AggregateFunction<IN, ACC, OUT>
IN是输入类型,ACC是中间聚合状态类型,OUT是输出类型,是聚合统计当前窗口的数据
- 全窗口函数 apply(new processWindowFunction(){ })
- 窗口先缓存该窗口所有元素,等窗口的全部数据收集起来后再触发条件计算
- 常见的全窗口聚合函数 windowFunction(未来可能弃用)、processWindowFunction(可以获取到窗口上下文 更多信息)
WindowFunction<IN, OUT, KEY, W extends Window>
IN是输入类型,OUT是输出类型,KEY是分组类型,W是时间窗
- 如果想处理每个元素更底层的API的时候用
对数据进行解析 ,process对每个元素进行处理,相当于 map+flatMap+filter
process(new KeyedProcessFunction(){processElement、onTimer})