窗口
在Flink中,窗口(Window)是一种将流数据划分为有限大小的块进行处理的机制。窗口可以根据时间或者其他的某种标准将输入数据流划分为不同的部分,并在每个窗口内对数据进行计算和聚合。
Flink支持多种窗口类型,如滚动窗口、滑动窗口、会话窗口等。其中,滚动窗口的大小固定且不重叠,而滑动窗口的大小可以重叠且可以指定滑动的步长;会话窗口是基于一定的间隙来定义的,当两个数据之间的时间差超过了指定的间隙时,则会话结束。
滚动窗口
滑动窗口
会话窗口
会话窗口的 assigner 会把数据按活跃的会话分组。 与滚动窗口和滑动窗口不同,会话窗口不会相互重叠,且没有固定的开始或结束时间。 会话窗口在一段时间没有收到数据之后会关闭,即在一段不活跃的间隔之后。 会话窗口的 assigner 可以设置固定的会话间隔(session gap)或 用 session gap extractor 函数来动态地定义多长时间算作不活跃。 当超出了不活跃的时间段,当前的会话就会关闭,并且将接下来的数据分发到新的会话窗口。
在我的实际应用中,回话窗口常呗用于低频次数据,比如每天只有一条数据,但是需要按天统计,这时候就可以使用会话窗口,当一天内没有数据时,会话窗口会关闭,然后下一天的数据会被分配到新的会话窗口中。
实际应用
processingTime & eventTime
场景:消费kafka数据,如果使用processingTime(kafka到达flink时的时间),当服务都正常运行时,程序一般是没问题的,但可能存在kafka数据和flink系统时间的一些误差(视实际应用而定)。但当flink程序停止,kafka积压了一些数据时,当flink启动,重新消费kafka数据时,我们需要根据时间计算的数据就会出现错误,因为此时的processingTime没有和kafka数据对齐,不只是一点误差的问题了。
这种情况下,就应该以eventTime为准,即将kafka数据的时间,作为watermark,flink处理数据时也以eventTime为时间窗口,这样当上述情况出现时,flink可以从上次kafka的commited offset继续消费,并已数据的实际时间为时间轴进行计算。
窗口关闭机制
当使用processingTime时,程序会根据系统时间,自动关闭窗口,并计算。因为使用processTime时,不依赖数据的时间。
e.g. 2023-03-34 10:00:01到达一条数据,当使用1min size,20s slide的SlidingProcessingTimeWindows时,系统会在2023-03-34 10:00:19,2023-03-34 10:00:39,2023-03-34 10:00:59 关闭对应 窗口,期间进行一系列的计算。
当使用eventTime时,程序不会自动关闭窗口,当有一条超过时间窗口的数据来时才会触发关闭,并执行对应的计算。
e.g. 当使用1min size,20s slide的SlidingEventTimeWindows时,会出现如下情况:
2023-03-34 10:00:01 到达第一条数据, 基于这个时间的窗口开启并开始计算
2023-03-34 10:00:10 符合时间,在20s以内(小于窗口结束时间:2023-03-34 10:00:19.999),窗口未关闭,继续计算
2023-03-34 10:00:15 符合时间,在20s以内小于窗口结束时间:2023-03-34 10:00:19.999),窗口未关闭,继续计算
2023-03-34 10:00:21 超过窗口时间,在20s以外,窗口未关闭,计算出在第一个slide窗口有3条数据, 同时2023-03-34 10:00:21 代表下一个窗口开始计算
此时假如 有一条 2023-03-34 10:00:18 的数据到达,如果未设置等待超时数据,则会被丢弃。
以上也是处理乱序数据的一种方式,当数据乱序时,会等待一段时间,如果在这段时间内,没有超过窗口时间的数据到达,则会关闭窗口,计算出结果。
当使用processTime时,程序会根据系统时间,自动关闭窗口,并计算。因为使用processTime时,不依赖数据的时间。
窗口函数
增量计算
增量计算指的是窗口保存一份中间数据,每流入一个新元素,新元素与中间数据两两合一,生成新的中间数据,再保存到窗口中.
全量计算
全量计算指的是窗口先缓存该窗口所有元素,等到触发条件后对窗口内的全量元素执行计算。
- ReduceFunction(增量计算)
- AggregateFunction(增量计算)
- ProcessWindowFunction(全量计算)
window & windowAll
Flink中的窗口(Window)是对数据流(DataStream)进行拆分和分析的一种方式。在窗口中,数据被划分为多个小块(Window),然后可以对每个小块进行聚合操作。Flink支持两种窗口类型:时间窗口(Time Window)和计数窗口(Count Window)。
时间窗口将数据按照时间段进行划分,例如每5秒钟为一个窗口,每个窗口内的数据是这5秒钟内到达的所有数据。常见的时间窗口有滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)和会话窗口(Session Window)等。
计数窗口将数据按照数量进行划分,例如每10条数据为一个窗口。常见的计数窗口有滚动计数窗口(Tumbling Count Window)和滑动计数窗口(Sliding Count Window)等。
除了基于数据流的窗口(DataStream Window)之外,Flink还提供了基于数据集(DataSet)的窗口(DataSet Window)。其中,windowAll是一种特殊的窗口类型,它不对数据进行拆分,而是将整个数据集作为一个窗口进行处理。
windowAll适用于需要对整个数据集进行聚合操作的场景,例如对某个文件中的所有数据进行求和或计算平均值等操作。由于windowAll不进行拆分,所以在处理大规模数据时可能会导致内存溢出或性能问题,因此需要谨慎使用。
总之,window和windowAll都是Flink中用于数据分析和聚合的工具,可以根据实际业务场景选择合适的窗口类型来进行处理。