复习
Flink 可以基于几种不同的 时间 概念来处理数据(详见 链接):
事件时间: 指的是数据本身携带的时间。这个时间是在事件产生时的时间。
摄入时间: 指的是数据进入 Flink 的时间;在系统内部,会把它当做事件时间来处理。
处理时间: 指的是执行具体操作时的机器时间(大家熟知的绝对时间, 例如 Java的 System.currentTimeMillis()) )
时间属性
基于时间的 window 操作,需要有时间属性,因此,表就需要提供 时间属性,以及支持时间相关的操作。
指定方式:
- 可以在用
CREATE TABLEDDL创建表的时候指定 - 可以在 DataStream 中指定
- 也可以在定义 TableSource 时指定
一旦时间属性定义好,就可以像 普通列 一样使用,也可以在 时间相关的操作中使用。
注意1:只要时间属性没有被修改,而是简单地从一个表传递到另一个表,它就仍然是一个有效的时间属性
注意2:时间属性可以像普通的时间戳字段一样,使用和计算。一旦时间属性用于 计算,就 变成普通的时间戳。普通的时间戳是 无法跟 Flink 的时间以及watermark等一起使用的,所以 普通的时间戳就 无法 用在时间相关的操作中。
事件时间
三种时间中,最常用的就是 事件时间
ddl 中定义
CREATE TABLE user_actions (
user_name STRING,
data STRING,
user_action_time TIMESTAMP(3),
-- 声明 user_action_time 是事件时间属性,并且用 延迟 5 秒的策略来生成 watermark
WATERMARK FOR user_action_time AS user_action_time - INTERVAL '5' SECOND
) WITH (
...
);
解释:
TIMESTAMP(3):表示精确到毫秒,如:2020-04-15 20:13:40.564INTERVAL:是关键字
查询
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);
时间类型
Flink 支持和在 TIMESTAMP 类型和 TIMESTAMP_LTZ 类型上定义事件时间。
TIMESTAMP
如果数据中的时间戳表示为 年-月-日-时-分-秒,则通常为 不带时区 信息的字符串值,例如:2020-04-15 20:13:40.564,建议类型为:TIMESTAMP
TIMESTAMP_LTZ
如果数据中的时间戳数据表示为一个纪元时间,通常是一个 long 值,例如:1618989564564,建议类型为: TIMESTAMP_LTZ
CREATE TABLE user_actions (
user_name STRING,
data STRING,
ts BIGINT,
time_ltz AS TO_TIMESTAMP_LTZ(ts, 3), -- 转成带有时区的 TIMESTAMP
-- 声明 time_ltz 是事件时间属性,并且用 延迟 5 秒的策略来生成 watermark
WATERMARK FOR time_ltz AS time_ltz - INTERVAL '5' SECOND
) WITH (
...
);
查询:
SELECT TUMBLE_START(time_ltz, INTERVAL '10' MINUTE), COUNT(DISTINCT user_name)
FROM user_actions
GROUP BY TUMBLE(time_ltz, INTERVAL '10' MINUTE);