flink1.12.x SQL:事件时间和watermark,时间类型(TIMESTAMP和TIMESTAMP_LTZ)

复习

Flink 可以基于几种不同的 时间 概念来处理数据(详见 链接):

  • 事件时间: 指的是数据本身携带的时间。这个时间是在事件产生时的时间。

  • 摄入时间: 指的是数据进入 Flink 的时间;在系统内部,会把它当做事件时间来处理。

  • 处理时间: 指的是执行具体操作时的机器时间(大家熟知的绝对时间, 例如 Java的 System.currentTimeMillis()) )

时间属性

基于时间的 window 操作,需要有时间属性,因此,表就需要提供 时间属性,以及支持时间相关的操作。

指定方式:

  • 可以在用 CREATE TABLE DDL创建表的时候指定
  • 可以在 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.564

  • INTERVAL:是关键字

查询

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);

原文出处:/show_1IX4EqYZAZoS.html