Flink 时间特性及sql窗口

Flink 时间特性及sql窗口

一、概述

  • 基于时间的操作(比如 Table API 和 SQL 中窗口操作),需要定义相关的时间语义和时间数据来源的信息
  • Table 可以提供一个逻辑上的时间字段,用于在表处理程序中,指示时间和访问相应的时间戳
  • 时间属性,可以是每个表schema的一部分。一旦定义了时间属性,它就可以作为一个字段引用,并且可以在基于时间的操作中使用
  • 时间属性的行为类似于常规时间戳,可以访问,并且进行计算

二、定义处理时间(Processing Time)

处理时间语义下,允许表处理程序根据机器的本地时间生成结果。它是时间的最简单概念。它既不需要提取时间戳,也不需要生成 watermark。

由三种方式可以生成proctime:

  1. 由DataSream转换成表时
  2. 定义Table Schema时
  3. 创建表的DDL时

2.1 由DataSream转换成表时

在定义Table Schema期间,可以使用.proctime,指定字段名义处理时间字段。

proctime属性只能通过附加逻辑字段,来扩展物理schema,因此,只能在schema定义的末尾来定义它。

Table dataTable = tableEnv.fromDataStream(dataStream, "id, timestamp as ts, temperature as temp, **pt.proctime**");

2.2 定义Table Schema时

.withSchema(new Schema()
            .field("id", DataTypes.STRING())
            .field("timestamp",DataTypes.BIGINT())
            .field("temperature",DataTypes.DOUBLE())
            .**field("pt",DataTypes.TIMESTAMP(3))**
            .**proctime()**
           )

2.3 创建表的DDL中

String sinkDDL =
  "create table dataTable (" +
  " id varchar(20) not null, " +
  " ts bigint, " +
  " temperature double, " +
  " pt AS PROCTIME() " +
  " ) with (" +
  " 'connector.type' = 'filesystem', " +
  " 'connector.path' = '/sensor.txt', " +
  " 'format.type' = 'csv')";
tableEnv.sqlUpdate(sinkDDL);

测试代码

package com.root.table;

import com.root.SensorReading;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.java.StreamTableEnvironment;
import org.apache.flink.types.Row;

/**
 * @author Kewei
 * @Date 2022/3/8 9:37
 */

public class TableTest7_Time {
   
   
    public static void main(String[] args) throws Exception {
   
   
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);

        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);

        DataStreamSource<String> inputStream = env.readTextFile("data/sensor.txt");
        SingleOutputStreamOperator<SensorReading> dataStream = inputStream.map(line -> {
   
   
            String[] fields = line.split(",");
            return new SensorReading(fields[0], new Long(fields[1]), new Double(fields[2]));
        })

        // DataStream转换为Table,设置当前运行时间pt.proctime
        Table dataTable = tableEnv.fromDataStream(dataStream, "id, timestamp as ts, temperature as temp, pt.proctime");

        dataTable.printSchema();
        tableEnv.toAppendStream(dataTable, Row.class).print();

        env.execute();
    }
}

三、定义事件时间(Event Time)

  • 事件时间语义,允许表处理程序根据每个记录中包含的时间生成结果。这样即使在有乱序事件或者延迟事件时,也可以获得正确的结果。
  • 为了处理无序事件,并区分流中的准时和迟到事件;Flink需要从事件数据中,提取时间戳,并用来推送事件时间的进展
  • 定义事件事件,同样有三种方法:
    1. 由DataStream转换成表时指定
    2. 定义Table Schema时指定
    3. 在创建表的DDL中定义

3.1 由DataStream转换成表时

  1. 由DataStream转换成表时,指定时间(推荐)
  2. 在DataStream转换成Table,使用.rowtime可以定义事件事件属性
  3. 注意需要先指定好事件时间,打开使用事件时间的设置
Table dataTable1 = tableEnv.fromDataStream(dataStream, "id, timestamp.rowtime, temperature");
Table dataTable2 = tableEnv.fromDataStream(dataStream, "id, timestamp, temperature,rt.rowtime");
// rowtime的位置不受限制

3.2 定义Table Schema时

.withSchema(new Schema()
            .field("id", DataTypes.STRING())
            .field("timestamp",DataTypes.BIGINT
### 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
发出的红包

打赏作者

努力生活的黄先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值