Flink 之 级联窗口计算

        在上一篇文章Flink 之 滚动窗口/滑动窗口/会话窗口/OVER窗口中分别介绍了 滚动窗口、滑动窗口、会话窗口以及OVER窗口,接下来本篇文章给大家介绍一下窗口中的最后一种:级联窗口

一、概述

        在 Flink 中,级联窗口是指多个窗口之间存在包含重叠关系的数据处理模式。它允许我们在不同的时间范围内对数据进行聚合和分析。简单来说,就是将数据流分割成多个时间段(窗口)来处理,这些窗口可以是嵌套的,也可以是重叠的。

        想象一下,我们有一个实时数据流,包含用户的点击数据。我们可能希望在不同的时间粒度上进行分析,比如每分钟、每小时和每天的点击量统计。级联窗口允许我们同时进行这些不同时间粒度的统计,而不需要多次遍历数据,这样可以复用中间计算结果,避免重复消费数据。

二、案例

        请注意,Rowtime 列在经过窗口操作后,其 Event Time 属性将丢失,为了在下一个窗口继续使用水印功能,可以使用辅助函数 TUMBLE_ROWTIME 代替 TUMBLE_END,此处以滚动窗口为例同理:HOP_ROWTIME 代替 HOP_END ,SESSION_ROWTIME 代替 SESSION_END。

2.1 背景

        假设你有一个在线购物平台的订单数据流,每条数据记录了订单的生成时间和订单金额。你希望通过级联窗口计算来实现以下目标:

  1. 每分钟计算订单总金额。
  2. 每3分钟计算前五分钟内每分钟订单总金额的平均值。

2.2 具体实现

2.2.1 代码

CREATE TEMPORARY TABLE orders (
    order_id INT,
    order_time TIMESTAMP(3),
    amount DOUBLE,
    WATERMARK FOR order_time AS order_time - INTERVAL '3' SECOND
) WITH (
    'connector' = 'faker',
    'fields.order_id.expression' = '#{number.numberBetween ''1'',''1000''}',
    'fields.order_time.expression' = '#{date.past ''5'',''SECONDS''}',
    'fields.amount.expression' = '#{number.randomDouble ''2'',''1'',''500''}'
);

CREATE TEMPORARY TABLE result1 (
    window_start TIMESTAMP(3),
    window_end TIMESTAMP(3),
    total_amount DOUBLE
) WITH (
    'connector' = 'print',
      'logger'='true',
      'print-identifier' = 'o1' -- 在日志中通过数据结果标识检索信息。

);

CREATE TEMPORARY TABLE result2 (
    window_start_3m TIMESTAMP(3),
    window_end_3m TIMESTAMP(3),
    avg_amount DOUBLE
) WITH (
    'connector' = 'print',
    'logger'='true',
    'print-identifier' = 'o2'
);


CREATE TEMPORARY VIEW orders_view
AS SELECT 
    TUMBLE_START(order_time, INTERVAL '1' MINUTE) AS window_start,
    TUMBLE_ROWTIME(order_time, INTERVAL '1' MINUTE) AS window_end,
    SUM(amount) AS total_amount
FROM orders
GROUP BY TUMBLE(order_time, INTERVAL '1' MINUTE);
;


BEGIN STATEMENT SET;

INSERT INTO result1
SELECT 
    window_start,
    window_end,
    total_amount
FROM orders_view
;

INSERT INTO result2
SELECT 
    TUMBLE_START(window_end, INTERVAL '3' MINUTE) AS window_start_3m,
    TUMBLE_ROWTIME(window_end, INTERVAL '3' MINUTE) AS window_end_3m,
    AVG(total_amount) AS avg_amount
FROM orders_view
GROUP BY TUMBLE(window_end, INTERVAL '3' MINUTE);

END;

2.2.2 结果

o1> +I[2024-08-08T00:11, 2024-08-08T00:11:59.999, 3.499849031999989E7]
o2> +I[2024-08-08T00:09, 2024-08-08T00:11:59.999, 3.499849031999989E7]


o1> +I[2024-08-08T00:12, 2024-08-08T00:12:59.999, 1.470114747000013E8]
o1> +I[2024-08-08T00:13, 2024-08-08T00:13:59.999, 1.4683286163000003E8]
o1> +I[2024-08-08T00:14, 2024-08-08T00:14:59.999, 1.472058926299993E8]
o2> +I[2024-08-08T00:12, 2024-08-08T00:14:59.999, 1.470167429866669E8]

o1> +I[2024-08-08T00:15, 2024-08-08T00:15:59.999, 1.4709021188999993E8]
o1> +I[2024-08-08T00:16, 2024-08-08T00:16:59.999, 1.470459928700004E8]
o1> +I[2024-08-08T00:17, 2024-08-08T00:17:59.999, 1.470872165200014E8]
o2> +I[2024-08-08T00:15, 2024-08-08T00:17:59.999, 1.470744737600006E8]

        给大家展示前几条数据,其中, “o1” 标识的是每分钟聚合数据,“o2” 标识的是通过 “o1”数据得到的每3分钟聚合数据。

        第一个“o1” 数据,它的窗口时间分别是:2024-08-08T00:11, 2024-08-08T00:11:59.999,SUM(amount)  == 3.499849031999989E7;第一个“o2” 数据,它的窗口时间分别是:2024-08-08T00:09, 2024-08-08T00:11:59.999,AVG(amount)  == 3.499849031999989E7,它俩窗口结束时间都是一样的,只不过 “o2”的开始时间比“o1” 早2分钟,窗口大小3分钟,而 “o1”窗口大小1分钟,符合逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值