Flink SQL之ProcessTime与EventTime的使用

本文详细介绍了Apache Flink SQL中处理时间(ProcessTime)和事件时间(EventTime)的概念及使用方法。通过创建表的DDL定义时间属性,以及在DataStream到Table转换时定义时间属性,展示了如何利用这两种时间属性进行基于时间的查询,包括窗口聚合、水印策略等。此外,还提供了多个代码示例来说明如何在实际操作中应用ProcessTime和EventTime。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)时间属性

  • 处理时间 指的是执行具体操作时的机器时间
  • 事件时间 指的是数据本身携带的时间。这个时间是在事件产生时的时间。

时间属性可以是每个表模式的一部分。当通过CREATETABLE DDL或创建表格时定义。一旦定义了时间属性,就可以将其引用为字段并在基于时间的操作中使用。只要时间属性没有被修改,并且只是从查询的一部分转发到另一部分,它仍然是有效的时间属性。时间属性的行为类似于常规时间戳,可用于计算

(2)ProcessTime

  • 在创建表的 DDL 中定义
  • 在 DataStream 到 Table 转换时定义
  • 使用 TableSource 定义(Flink1.12中不建议使用)

(2.1)在创建表的 DDL 中定义

  • 处理时间属性可以在创建表的 DDL 中用计算列的方式定义,用 PROCTIME() 就可以定义处理时间。
  • 处理时间是基于机器的本地时间来处理数据,它既不需要从数据里获取时间,也不需要生成watermark。
CREATE TABLE user_actions (
  user_name STRING,
  data STRING,
  user_action_time AS PROCTIME() -- 声明一个额外的列作为处理时间属性
) WITH (
  ...
);

SELECT TUMBLE_START(user_action_time, INTERVAL '10' MINUTE), COUNT(DISTINCT user_name)
FROM user_actions
GROUP BY TUMBLE(user_action_time, INTERVAL '10' MINUTE);

数据源:

100,技术部
200,市场部
300,营销部
400,采购部

代码演示:

package com.aikfk.flink.sql;

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;


/**
 * @author :caizhengjie
 * @description:TODO
 * @date :2021/4/5 10:32 下午
 */
public class ProcessTimeSQL {
   
    public static void main(String[] args) throws Exception {
   
        // 1.准备环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2.创建TableEnvironment(Blink planner)
        EnvironmentSettings settings = EnvironmentSettings.newInstance().inStreamingMode().useBlinkPlanner().build();
        StreamTableEnvironment tableEnvironment = StreamTableEnvironment.create(env , settings);

        // 3.文件path
        String filePath = "/Users/caizhengjie/IdeaProjects/aikfk_flink/src/main/java/resources/dept.csv";

        // 4.DDL-- 声明一个额外的列作为处理时间属性
        String ddl = "create table dept (\n" +
                " dept_id STRING,\n" +
                " dept_name STRING,\n" +
                " user_action_time AS PROCTIME()\n" +
                ") WITH (\n" +
                " 'connector.type' = 'filesystem',\n" +
                " 'connector.path' = '"+filePath+"',\n" +
                " 'format.type' = 'csv'\n" +
                ")";

        // 5.创建一个带processtime字段的表
        tableEnvironment.executeSql(ddl);

        
<think>好的,用户想了解Flink SQL中时间函数的使用方法和示例。首先我需要回忆一下Flink SQL支持的时间函数,包括系统内置的和自定义的可能。根据提供的引用内容,特别是引用[2]提到了窗口函数和其他常见函数,引用[4]提到了自定义函数的使用,但用户的问题主要聚焦于时间函数,可能需要涉及处理时间、事件时间以及相关的窗口操作。 首先,系统内置的时间函数包括CURRENT_TIMESTAMP、DATE_FORMAT、EXTRACT等,这些是基础的时间处理函数。然后,时间属性在Flink中分为处理时间和事件时间,用户可能需要知道如何定义这两种时间属性,例如在DDL中指定或者通过PROCTIME()函数。 接下来是窗口函数,比如TUMBLE、HOP、SESSION等,这些在流处理中非常重要。需要给出具体的SQL示例,展示如何将时间字段作为窗口参数,并配合聚合函数使用。例如,TUMBLE_START和TUMBLE_END来获取窗口的开始和结束时间。 另外,用户可能需要了解如何将字符串转换为时间类型,或者提取时间的某个部分,比如年、月、日等。这里可能需要用到TO_TIMESTAMP和EXTRACT函数。 还需要注意,在引用中提到自定义函数的注册和使用,例如引用[2]中的hashcode函数,但时间函数主要是内置的,不过如果有自定义的时间处理需求,可能需要用到UDF,但用户的问题可能更关注内置函数。 此外,引用[3]和[4]提到Flink SQL的自定义函数加载和解析,但用户的问题不涉及自定义函数,所以可能不需要深入这部分,除非用户的问题扩展到自定义时间处理函数,但目前应集中在系统内置函数。 需要检查是否有遗漏的时间函数,比如INTERVAL的使用,或者时间差计算函数DATEDIFF等。同时,可能需要给出水印设置的例子,因为事件时间处理通常需要水印,这涉及到时间属性的定义。 最后,需要确保示例的正确性,比如在DDL中定义时间字段、指定水印,以及在查询中使用窗口函数和聚合。同时,要提醒用户关于时间函数在使用时的一些注意事项,比如时区处理,或者时间格式的正确性。 总结回答结构:先介绍时间函数分类,再分点讲解内置函数、时间属性定义、窗口函数,每个部分给出示例,最后注意事项。确保使用正确的$$...$$格式和行内$...$,并生成相关问题。</think>### Flink SQL 时间函数用法详解 #### 一、时间函数分类 Flink SQL 的时间函数主要分为以下几类: 1. **系统内置时间函数**:如 `CURRENT_TIMESTAMP`、`DATE_FORMAT`、`EXTRACT` 等 2. **时间属性定义函数**:用于指定事件时间(Event Time)或处理时间(Processing Time) 3. **窗口函数**:时间窗口相关的 `TUMBLE`、`HOP`、`SESSION` 等 --- #### 二、内置时间函数示例 1. **获取当前时间** ```sql SELECT CURRENT_TIMESTAMP AS current_ts; -- 返回格式: 2023-09-15 14:30:00.123 ``` 2. **时间格式转换** ```sql SELECT DATE_FORMAT(ts, 'yyyy-MM-dd HH:mm') AS formatted_ts, -- 将时间戳格式化为字符串 TO_TIMESTAMP('2023-09-15 14:30:00', 'yyyy-MM-dd HH:mm:ss') AS converted_ts -- 字符串转时间戳 FROM events; ``` 3. **时间提取** ```sql SELECT EXTRACT(YEAR FROM ts) AS year, EXTRACT(HOUR FROM ts) AS hour FROM events; ``` --- #### 三、时间属性定义 在 Flink DDL 中定义时间属性: ```sql CREATE TABLE sensor ( id STRING, ts BIGINT, -- 将ts字段转换为TIMESTAMP类型,并声明为事件时间 event_time AS TO_TIMESTAMP(FROM_UNIXTIME(ts / 1000)), WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND -- 定义水位线 ) WITH (...); ``` --- #### 四、窗口函数使用 1. **滚动窗口示例** ```sql SELECT TUMBLE_START(event_time, INTERVAL '1' HOUR) AS window_start, COUNT(id) AS cnt FROM sensor GROUP BY TUMBLE(event_time, INTERVAL '1' HOUR); ``` 2. **滑动窗口示例** ```sql SELECT HOP_START(event_time, INTERVAL '5' MINUTE, INTERVAL '15' MINUTE) AS window_start, AVG(temperature) AS avg_temp FROM sensor GROUP BY HOP(event_time, INTERVAL '5' MINUTE, INTERVAL '15' MINUTE); ``` --- #### 五、时间间隔计算 ```sql SELECT DATEDIFF(ts1, ts2) AS day_diff, -- 计算两个时间戳的天数差 TIMESTAMPDIFF(MINUTE, start_time, end_time) AS minute_diff FROM time_table; ``` --- #### 六、注意事项 1. 事件时间必须配合 `WATERMARK` 定义使用[^2] 2. 处理时间可通过 `PROCTIME()` 函数直接声明: ```sql SELECT id, PROCTIME() AS process_time FROM sensor; ``` 3. 时区设置需通过 `table.local-time-zone` 配置参数统一管理 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

<一蓑烟雨任平生>

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

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

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

打赏作者

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

抵扣说明:

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

余额充值