窗口:将无限数据切割成有限的“数据块”进行处理,以便更高效地处理无界流
在处理无界数据流时,把无界流进行切分,每一段数据分别进行聚合,结果只输出一次。这就相当于将无界流的聚合转化为了有界数据集的聚合
在 Flink 中,窗口可以把流切割成有限大小的多个“存储桶”(bucket);每个数据都会分发到对应的桶中,当到达窗口结束时间时,就对每个桶中收集的数据进行计算处理
窗口处理过程:
窗口创建:
Flink 中窗口并不是静态准备好的,而是动态创建——当有落在这个窗口区间范围的数据达到时,才创建对应的窗口
驱动类型,即窗口以什么标准来开始和结束数据的截取
按照时间段截取:时间窗口
窗口大小:用结束时间减去开始时间,得到这段时间的长度,就是窗口的大小
Flink中用TimeWindow
类来表示时间窗口:
可以看到,窗口的时间范围是左闭右开的区间
按照固定的个数截取:计数窗口
计数窗口基于元素的个数来截取数据,到达固定的个数时就触发计算并关闭窗口
滚动窗口有固定的大小,是一种对数据进行“均匀切片”的划分方式;
窗口之间没有重叠,也不会有间隔,是“首尾相接”的状态,所以每个数据都会被分配到一个窗口,而且只会属于一个窗口
滚动窗口可以基于时间定义,也可以基于数据个数定义;需要的参数只有一个,就是窗口的大小(window size)。比如我们可以定义一个长度为 1 小时的滚动时间窗口,那么每个小时就会进行一次统计;或者定义一个长度为 10 的滚动计数窗口,就会每 10 个数进行一次统计
滑动窗口的大小也是固定的,但窗口之间并不是首尾相接的,而是可以“错开”一定的位置
参数:窗口大小和滑动步长
窗口大小是固定的,代表了两个窗口结束时间的间隔
滑动步长代表了窗口计算的频率。滑动的距离代表了下个窗口开始的时间间隔
当滑动步长小于窗口大小时,滑动窗口就会出现重叠,这时数据也可能会被同时分配到多个窗口中;具体的个数,就由窗口大小和滑动步长的比值来决定;
比如我们定义的窗口长度为 1 小时、滑动步长为 30 分钟,那么对于 8 点 55 分的数据,应该同时属于[8 点, 9 点)和[8 点半, 9 点半)两个窗口;而对于 8 点 10 分的数据,则同时属于[8点, 9 点)和[7 点半, 8 点半)两个窗口
Flink 中的计数窗口(Count Window),底层就是用全局窗口实现的
①窗口的创建:窗口的类型和基本信息由窗口分配器指定,但是窗口的创建是由数据驱动创建的,当第一个应该属于这个窗口的数据元素到达时,就会创建对应的窗口
②窗口计算的触发:触发器触发窗口函数的执行,进行数据计算
③窗口的销毁:一般情况下,当时间达到了结束点,就会直接触发计算输出结果、进而清除状态销毁窗口;在特殊的场景下,窗口的销毁和触发计算会有所不同
事件时间语义下,如果设置了允许延迟,那么在水位线到达窗口结束时间时,仍然不会销毁窗口;窗口真正被完全删除的时间点,是窗口的结束时间加上用户指定的允许延迟时间
④窗口API: