Flink Table API watermarks

1,105 阅读2分钟

在Table API和SQL中,Flink将数据看成是一张表,流数据就是一张无限追加的表,而批数据就是一张有限的数据表。这样的无限追加的表就称之为动态表。

动态表查询

动态表的查询结果还是一个动态表,也是一张无限追加的表 动态表查询结果可以分为两种:

  1. 新的数据进来之后,统计所有的历史数据,然后更新结果表。这种查询需要维护更多的状态。在不设置窗口处理的时候是这种查询。 image.png

  2. 新的数据进来之后,统一更新的部分,并将更新之后的数据追加到结果表中 image.png

时间字段 & Watermarks

对于无限增长的动态表处理,在不设置窗口的时候,如果不设置watermarks,那么无限的数据一定会是的内存OOM。
在Table API中如何定义watermarks呢:

定义Event time

定义在表DDL中

CREATE TABLE user_actions (
  user_name STRING,
  data STRING,
  user_action_time TIMESTAMP(3),
  -- 定义user_action_time作为event time并且延时5秒产生的Watermarks,不是Watermarks宽度
  WATERMARK FOR user_action_time AS user_action_time - INTERVAL '5' SECOND
) WITH (
  ...
);

时间字段的类型可以是TIMESTAMPTIMESTAMP_LTZ.

  • TIMESTAMP: 是不带有timezone的timestamp
  • TIMESTAMP_LTZ: 是带有本地timezone的timestamp
-- 设置timezone
SET table.local-time-zone=UTC;

定义在DataStream转换成Table中

stream = inputStream.assignTimestampAndWatermarks(...);
tEnv.fromDataStream(stream, $("user_name"),...,$("time").rowtime(),...);

定义在TableSource中

重写getRowtimeAttributeDescriptors(),重写这个方法来定义时间字段的名称

使用watermarks查询

SQL:

select TUMBLE_START(time, INTERVAL '10' MINUTE),COUNT(DINSTINCT user_name) 
from table_name 
group by TUMBLE(time, INTERVAL '10' MINUTE)

Table API:

table.window(Tumble.over(lit(10).minutes()))
    .on($("time"))
    .as("myWindow")

定义Processing Time

定义在表DDL中

CREATE TABLE user_actions (
  user_name STRING,
  data STRING,
  -- 定义user_action_time作为processing time
  user_action_time AS PROCTIME() 
) WITH (
  ...
);

定义在DataStream转换成Table中

stream = inputStream.assignTimestampAndWatermarks(...);
Table table = tEnv.fromDataStream(stream, $("user_name"), $("data"), $("user_action_time").proctime());

定义在TableSource中

重写getProctimeAttribute(),重写这个方法来定义时间字段的名称

使用watermarks查询

SQL:

select TUMBLE_START(time, INTERVAL '10' MINUTE),COUNT(DINSTINCT user_name) 
from table_name 
group by TUMBLE(time, INTERVAL '10' MINUTE)

Table API:

table.window(Tumble.over(lit(10).minutes()))
    .on($("time"))
    .as("myWindow")

Table API中的窗口

  • TUMBLE(滚动窗口):TUMBLE(time, INTERVAL '1' HOURS)
  • HOP(滑动窗口):HOP(time, INTERVAL '2' HOURS, INTERVAL '1' HOURS,)
  • SESSION(会话窗口):SESSION(time, INTERVAL '1' MINUTE)