FlinkSql中的窗口

        窗口可以将无界流切割成大小有限的“桶”(bucket)来做计算,通过截取有限数据集来处理无限的流数据。

窗口表值函数(Window TVF)

        从 1.13 版本开始,Flink 开始使用窗口表值函数(Windowing table-valued functions,
Windowing TVFs)来定义窗口。窗口表值函数是 Flink 定义的多态表函数(PTF),可以将表
进行扩展后返回
。表函数(table function)可以看作是返回一个表的函数。

        目前 Flink 提供了以下几个窗口 TVF:

  • 滚动窗口(Tumbling Windows);
  • 滑动窗口(Hop Windows,跳跃窗口);
  • 累积窗口(Cumulate Windows);
  • 会话窗口(Session Windows,目前尚未完全支持)。

        在窗口 TVF 的返回值中,除去原始表中的所有列,还增加了用来描述窗口的额外 3 个列:窗口起始点(window_start)、窗口结束点(window_end)、窗口时间(window_time)。起始点和结束点比较好理解,这里的“窗口时间”指的是窗口中的时间属性,它的值等于window_end - 1ms,所以相当于是窗口中能够包含数据的最大时间戳

滚动窗口(TUMBLE)

滚动窗口在 SQL 中的概念与 DataStream API 中的定义完全一样,是长度固定、时间对齐、无重叠的窗口,一般用于周期性的统计计算。在 SQL 中通过调用 TUMBLE()函数就可以声明一个滚动窗口,只有一个核心参数就是窗口大小(size)。在 SQL 中不考虑计数窗口,所以滚动窗口就是滚动时间窗口,参数中还需要将当前的时间属性字段传入;另外,窗口 TVF 本质上是表函数,可以对表进行扩展,所以还应该把当前查询的表作为参数整体传入。具体声明如下:

TUMBLE(TABLE EventTable, DESCRIPTOR(ts), INTERVAL '1' HOUR)

这里基于时间字段 ts,对表 EventTable 中的数据开了大小为 1 小时的滚动窗口。窗口会将表中的每一行数据,按照它们 ts 的值分配到一个指定的窗口中。

应用场景:统计每小时的pv,uv。

滑动窗口(HOP)

        滑动窗口的使用与滚动窗口类似,可以通过设置滑动步长来控制统计输出的频率。在 SQL中通过调用 HOP()来声明滑动窗口;除了也要传入表名、时间属性外,还需要传入窗口大小(size)
和滑动步长(slide)
两个参数。

HOP(TABLE EventTable, DESCRIPTOR(ts), INTERVAL '5' MINUTES, INTERVAL '1' HOURS));

这里我们基于时间属性 ts,在表 EventTable 上创建了大小为 1 小时的滑动窗口,每 5 分钟滑动一次。需要注意的是,紧跟在时间属性字段后面的第三个参数是步长(slide),第四个参数才是窗口大小(size)。

应用场景:每5分钟统计一下最近一小时的pv,uv。

累积窗口(CUMULATE)

        在实际应用中还会遇到这样一类需求:我们的统计周期可能较长,因此希望中间每隔一段时间就输出一次当前的统计值;与滑动窗口不同的是,在一个统计周期内,我们会多次输出统计值,它们应该是不断叠加累积的。这种特殊的窗口就叫作“累积窗口”(Cumulate Window),它会在一定的统计周期内进行累积计算。累积窗口中有两个核心的参数:最大窗口长度(max window size)和累积步长(step)。所谓的最大窗口长度其实就是我们所说的“统计周期”,最终目的就是统计这段时间内的数据。开始时,创建的第一个窗口大小就是步长 step;之后的每个窗口都会在之前的基础上再扩展 step 的长度,直到达到最大窗口长度。在 SQL 中可以用 CUMULATE()函数来定义,具体如下:

CUMULATE(TABLE EventTable, DESCRIPTOR(ts), INTERVAL '1' HOURS, INTERVAL '1' DAYS))
这里我们基于时间属性 ts,在表 EventTable 上定义了一个统计周期为 1 天、累积步长为 1 小时的累积窗口。注意第三个参数为步长 step ,第四个参数则是最大窗口长度。
使用场景:每小时统计一次当天的pv,uv。(如果用 1 天的滚动窗口,那需要到每天 24 点才会计算一次,输出频率太低;如果用滑动窗口,计算频率可以更高,但统计的就变成了“过去 24 小时的 PV”。所以我们真正希望的是,还是按照自然日统计每天的PV,不过需要每隔 1 小时就输出一次当天到目前为止的 PV 值)。

实际案例

每天的截⽌当前分钟的累计 money(sum(money),去重 id 数(count(distinct id))。每天代表渐进式窗⼝⼤⼩为 1 天,分钟代表渐进式窗⼝移动步⻓为分钟级别。

--数据源表
CREATE TABLE source_table (
 user_id BIGINT,
 money BIGINT,
 row_time AS cast(CURRENT_TIMESTAMP as timestamp(3)),
 WATERMARK FOR row_time AS row_time - INTERVAL '5' SECOND
) WITH (
...
);

-- 数据处理逻辑
SELECT   UNIX_TIMESTAMP(CAST(window_end AS STRING)) * 1000 as window_end 
        ,window_start
        ,sum(money) as sum_money
        ,count(distinct id) as count_distinct_id
FROM TABLE(CUMULATE(TABLE source_table,DESCRIPTOR(row_time),INTERVAL '60' SECOND,INTERVAL '1' DAY))
GROUP BY window_start
        ,UNIX_TIMESTAMP(CAST(window_end AS STRING)) * 1000

可以看到 Windowing TVF 滚动窗⼝的写法就是把 cumulate window 的声明写在了数据源的 Table ⼦句中,所以可理解为将表进行扩展后返回。

Window TVF ⽀持 Grouping Sets、Rollup、Cube

应⽤场景:实际的案例场景中,经常会有多个维度进⾏组合(cube)计算指标的场景。如果把每个维度组合 的代码写⼀遍,然后 union all 起来,这样写起来⾮常麻烦,⽽且会导致⼀个数据源读取多遍。

-- ⽤户访问明细表
CREATE TABLE source_table (
 age STRING,
 sex STRING,
 user_id BIGINT,
 row_time AS cast(CURRENT_TIMESTAMP as timestamp(3)),
 WATERMARK FOR row_time AS row_time - INTERVAL '5' SECOND
) WITH (
...
);

--处理逻辑
SELECT   UNIX_TIMESTAMP(CAST(window_end AS STRING)) * 1000 as window_end
        ,if(age is null, 'ALL', age) as age
        ,if(sex is null, 'ALL', sex) as sex
        ,count(distinct user_id) as bucket_uv
FROM TABLE(CUMULATE(TABLE source_table,DESCRIPTOR(row_time),INTERVAL '5' SECOND,INTERVAL '1' DAY))
GROUP BY window_start
        ,window_end
        ,GROUPING SETS (
         ()
         ,(age)
         ,(sex)
         ,(age, sex)
         )
;

⽬前 Grouping Sets 只在 Window TVF 中⽀持,不⽀持 Group Window Aggregation。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一章 整体介绍 2 1.1 什么是 Table API 和 Flink SQL 2 1.2 需要引入的依赖 2 1.3 两种 planner(old & blink)的区别 4 第二章 API 调用 5 2.1 基本程序结构 5 2.2 创建表环境 5 2.3 在 Catalog 注册表 7 2.3.1 表(Table)的概念 7 2.3.2 连接到文件系统(Csv 格式) 7 2.3.3 连接到 Kafka 8 2.4 表的查询 9 2.4.1 Table API 的调用 9 2.4.2 SQL 查询 10 2.5 将 DataStream 转换成表 11 2.5.1 代码表达 11 2.5.2 数据类型与 Table schema 的对应 12 2.6. 创建临时视图(Temporary View) 12 2.7. 输出表 14 2.7.1 输出到文件 14 2.7.2 更新模式(Update Mode) 15 2.7.3 输出到 Kafka 16 2.7.4 输出到 ElasticSearch 16 2.7.5 输出到 MySql 17 2.8 将表转换成 DataStream 18 2.9 Query 的解释和执行 20 1. 优化查询计划 20 2. 解释成 DataStream 或者 DataSet 程序 20 第三章 流处理的特殊概念 20 3.1 流处理和关系代数(表,及 SQL)的区别 21 3.2 动态表(Dynamic Tables) 21 3.3 流式持续查询的过程 21 3.3.1 将流转换成表(Table) 22 3.3.2 持续查询(Continuous Query) 23 3.3.3 将动态表转换成流 23 3.4 时间特性 25 3.4.1 处理时间(Processing Time) 25 3.4.2 事件时间(Event Time) 27 第四章 窗口(Windows) 30 4.1 分组窗口(Group Windows) 30 4.1.1 滚动窗口 31 4.1.2 滑动窗口 32 4.1.3 会话窗口 32 4.2 Over Windows 33 1) 无界的 over window 33 2) 有界的 over window 34 4.3 SQL 窗口的定义 34 4.3.1 Group Windows 34 4.3.2 Over Windows 35 4.4 代码练习(以分组滚动窗口为例) 36 第五章 函数(Functions) 38 5.1 系统内置函数 38 5.2 UDF 40 5.2.1 注册用户自定义函数 UDF 40 5.2.2 标量函数(Scalar Functions) 40 5.2.3 表函数(Table Functions) 42 5.2.4 聚合函数(Aggregate Functions) 45 5.2.5 表聚合函数(Table Aggregate Functions) 47
Flink SQL的JOIN操作可以和窗口一起使用,实现窗口上的JOIN计算,这可以在实时流处理非常有用。 窗口是数据流处理的一种重要概念,它可以将数据流按照时间或者数量等维度进行切分,然后对每个窗口内的数据进行计算Flink SQL支持多种类型的窗口,如滚动窗口、滑动窗口、会话窗口等。 在使用Flink SQL进行JOIN操作时,可以将JOIN条件和窗口条件进行结合,以获取更加精细的数据切分和计算结果。例如,可以将两个数据流按照时间窗口进行JOIN操作,计算出在指定时间窗口内符合条件的数据。 具体来说,Flink SQL的JOIN操作和窗口的结合有以下几个步骤: 1. 定义窗口:使用Flink SQL窗口函数,对数据流进行窗口切分,定义窗口大小和滑动步长等参数。 2. 分区数据:将数据流按照JOIN条件进行分区,将不同数据流符合条件的数据分配到同一个计算节点上。 3. 缓存数据:将分区后的数据缓存到内存或者磁盘,以供后续的JOIN计算使用。 4. JOIN计算:对缓存的数据按照JOIN条件进行JOIN计算,同时按照窗口条件进行分组计算计算出符合条件的数据。 5. 输出结果:将JOIN计算的结果输出到指定的目标位置,以供后续的查询分析使用。 总的来说,Flink SQL的JOIN操作和窗口的结合可以实现更加精细的数据切分和计算,可以在实时流处理实现更加复杂的数据分析和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值