Flink 窗口 概述

一:窗口简述

        Flink是一种流式计算引擎,主要是来处理无界数据流的,数据源源不断、无穷无尽。想要更加方便高效地处理无界流,一种方式就是将无限数据切割成有限的“数据块”进行处理,这就是所谓的“窗口”(Window)。 【把窗口理解成一个“桶”,Flink则可以把流切割成大小有限的“储存桶”,把数据分发到不同的桶里,每一个窗口都是一个桶。当窗口结束,就对每一个桶的数据进行收集处理】

二: 窗口的分类

        1)按照驱动类型分

              (1) 时间窗口

                            原理:建立一个窗口,在固定的额时间段内不断收集数据,到达结束时间的时候窗口结束收集数据,生成结果,窗口销毁。【就像地铁一样,间隔一段时间发车,无论车上有多少乘客,地铁都会往前开】

              (2)  计数窗口

                               原理:计数窗口基于元素的个数来截取数据,到达固定的个数时就触发计算并关闭窗口。每个窗口截取数据的个数,就是窗口的大小。基本思路是“人齐发车”

        2)按照窗口分配数据的规则分类(以下均为以时间驱动为例)

                        主要概念:窗口的大小,窗口的滑动步长【两个窗口重叠的部分】,会话间隔

                (1) 滚动窗口(Tumbling Windows)

                             滚动窗口有固定的大小,而且窗口之间不会重叠,每个数据都在一个窗口且只属于这个窗口。在一个固定时间内,接受数据的传入。到了截止时间,收集数据,输出结果。应用类型广泛,可以对每个时间做聚合统计。

                   c850e2e36a3f48bca15878796c5b9ec0.png

                (2) 滑动窗口  (Sliding Windows)

                                 当窗口大小大于窗口步长的时候就会出现滑动,滑动窗口会重叠,同时数据也会同时被分到多个窗口,滑动步长就代表了计算频率。适合计算结果更新较快的场景。

                              

                (3) 会话窗口   (Session Windows)

                                原理:基于“会话”来进行数据分组、如果相邻两个数据到来的时间间隔 小于指定大小,那么这两个数据在同一个窗口内。如果 大于则数据到了新的窗口,且前面的窗口关闭。  会话窗口长度,起始结束时间不确定。各个分区之间窗口没有任何关联。在规定的时间内没有数据到来触发一次计算。可以用于保持会话的场景下。

                (4) 全局窗口 (Global Windows)

                                把相同key的数据全部分配到一个窗口之中,窗口没有结束是不会触发计算的。如果希望对数据处理,需要定义一个触发器。

                     

三:窗口API

        1)按键分区(Keyed)和非按键分区(Non-Keyed

                        (1)按键分区窗口(Keyed Windows)

                                经过按键分区keyBy操作后,数据流会按照key被分为多条逻辑流(logical streams),这就是KeyedStream。基于KeyedStream进行窗口操作时,窗口计算会在多个并行子任务上同时执行。相同key的数据会被发送到同一个并行子任务,而窗口操作会基于每个key进行单独的处理。所以可以认为,每个key上都定义了一组窗口,各自独立地进行统计计算。

在代码实现上,我们需要先对DataStream调用.keyBy()进行按键分区,然后再调用.window()定义窗口。

stream.keyBy(...) .window(...)

                        (2)非按键分区(Non-Keyed Windows)

如果没有进行keyBy,那么原始的DataStream就不会分成多条逻辑流。这时窗口逻辑只能在一个任务(task)上执行,就相当于并行度变成了1。setParallelism(1)

在代码中,直接基于DataStream调用.windowAll()定义窗口。

stream.windowAll(...)

注意:对于非按键分区的窗口操作手动调大窗口算子的并行度也是无效的

四:窗口分配器

        1)Flink中的时间语义

                                到底是以哪种时间作为衡量的标准,就被成为“时间语义”

        2)时间窗口分配器

                                                (1) 处理时间的时间语义窗口

特征:

  • 基于处理节点的当前系统时间。
  • 实现简单,延迟低。
  • 适用于数据实时性要求高且乱序不多的场景。
  • 在处理乱序数据时,结果可能不准确。

应用场景:        

  • 监控系统指标(如CPU使用率、内存使用情况)。
  • 实时数据分析,延迟比准确性更重要的场景。

     

使用参数:                 

TumblingProcessingTimeWindows.of(Time.)     滚动窗口
SlidingProcessingTimeWindows.of(Time.)     滑动窗口
ProcessingTimeSessionWindows.withGap()  ProcessingTimeSessionWindows.withDynamicGap()     会话窗口

                                                

                                                (2) 处理事件的时间语义窗口 

特征:      

  • 基于事件的时间戳。
  • 处理乱序数据,通过Watermark机制来处理延迟事件。
  • 更加准确,适用于要求严格时间语义的场景。

实时场景:    

  • 实时日志分析(如用户行为分析、点击流分析)。
  • 需要严格时间顺序和准确性的场景,如金融交易分析。

使用参数:

TumblingEventTimeWindows.of(Time.)     滚动窗口
SlidingEventTimeWindows.of(Time.)     滑动窗口

EventTimeSessionWindows.withGap() 

EventTimeSessionWindows.withDynamicGap()

    会话窗口

       

        3)计数窗口分配器

countWindow(5) 计数窗口分配器  【滚动】  满足5条输出一次计算结果
countWindow(5,2) 计数窗口分配器  【滑动】  满足5条输出一次计算结果 , 每经过一个步长都有一个窗口-触发输出【第一次输出在第二条数据来的时候】

        4)全局窗口分配器

GlobalWindows.create()
### Flink SQL 窗口聚合概述 Flink SQL 支持多种类型的窗口操作来处理流数据,这些操作允许对一段时间内的事件进行聚合分析。对于不包含主键的数据表,可以通过定义时间属性并应用特定的时间窗口来进行有效的查询和统计[^1]。 ### 滚动窗口查询实例 当执行滚动窗口查询时,每条记录会被分配到一个固定大小且互不重叠的时间区间内。下面是一个具体的例子: 假设有一个名为 `clicks` 的输入表,其中包含了用户的点击行为以及发生的时间戳字段 `ts` 和水印声明用于表示事件时间。为了计算过去五分钟内每个广告ID (`ad_id`) 上发生的总点击次数,可以采用如下SQL语句: ```sql CREATE TABLE clicks ( user_name STRING, ad_id BIGINT, ts TIMESTAMP(3), WATERMARK FOR ts AS ts - INTERVAL '5' SECOND ) WITH (...); SELECT TUMBLE_START(ts, INTERVAL '5' MINUTE), -- 开始时间 ad_id, COUNT(*) as cnt_clicks FROM clicks GROUP BY TUMBLE(ts, INTERVAL '5' MINUTE), ad_id; ``` 此代码片段展示了如何创建带有时间特性的源表,并利用 `TUMBLE()` 函数实现按五分钟左右间隔划分的滚动窗口聚合操作。 ### CUMULATE累积窗口示例 除了标准的滑动或翻滚窗口外,还可以使用累加窗口(Cumulate Windows),它能够提供更加灵活的时间范围控制。例如,如果希望每隔两分钟输出一次最近十分钟内的统计数据,则可以用以下方式构建查询: ```sql SELECT CUMULATE(ts, INTERVAL '2' MINUTE, INTERVAL '10' MINUTE) as win_start, ad_id, SUM(click_count) OVER w as total_clicks_in_10min FROM clicks WINDOW w AS (PARTITION BY ad_id ORDER BY ts RANGE BETWEEN INTERVAL '10' MINUTE PRECEDING AND CURRENT ROW); ``` 这里引入了 `CUMULATE()` 来指定累积窗口参数,同时配合开窗子句实现了基于分区有序列化的累计求和逻辑。 ### 关于Windowing TVFs 值得注意的是,在新版Flink SQL 中推荐使用 Windowing Table Valued Functions(TVFs),因为它们不仅遵循SQL标准而且功能更为强大,比如支持像Top N这样的复杂运算;而传统的分组窗口仅限于做简单的聚合工作[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值