1. 通过proctime AS PROCTIME() 来指定
如下面flink ddl中使用 proctime AS PROCTIME() 来生产一个新的计算列,该计算列可当作处理时间来对待。
计算列常常被用在定义时间属性(见另一篇文章Flink Table API&SQL编程指南之时间属性(3),可以通过PROCTIME()函数定义处理时间属性,语法为proc AS PROCTIME()
。
除此之外,计算列可以被用作提取事件时间列,因为原始的事件时间可能不是TIMESTAMP(3)类型或者是存在JSON串中。
CREATE TABLE user_address (
userId BIGINT,
addressInfo VARCHAR,
proctime AS PROCTIME()
) WITH (
'connector' = 'kafka',
'properties.bootstrap.servers' = 'localhost:9092',
'topic' = 'tp02',
'format' = 'json',
'scan.startup.mode' = 'latest-offset'
)
2. 通过 for system_time as of 来指定
如下通过通过for system_time指定时间,并关联维表。在join的时候需要使用 FOR SYSTEM_TIME AS OF
,其中table1.proctime表示table1的proctime处理时间属性(计算列)。使用FOR SYSTEM_TIME AS OF table1.proctime
表示当左边表的记录与右边的维表join时,只匹配当前处理时间维表所对应的的快照数据(即关联维表当前最新的状态)。
在Temporal Table Join关联中,维表可能会不断变化,JOIN行为发生后,维表中的数据发生了变化(新增、更新或删除),则已关联的维表数据不会被同步变化。
SELECT column-names
FROM table1 [AS <alias1>]
[LEFT] JOIN table2 FOR SYSTEM_TIME AS OF table1.proctime [AS <alias2>]
ON table1.column-name1 = table2.key-name1
select
t1.*
from
( --临时队列
select *,PROCTIME() as proctime
from real_tmp_order_info_from_kafka
)t1
left join real_dim_order_info_to_hbase FOR SYSTEM_TIME AS OF t1.proctime t2 --维度关联最新订单状态
on t1.order_id = t2.order_id
where t2.order_id is null or t2.order_status='待处理'
3. 事件时间
事件时间属性可以通过 WATERMARK语句进行定义,事件时间会有乱序和延时到达的问题,proc
时间没有乱序和延时到达的情况,如下:
CREATE TABLE user_actions (
user_name STRING,
data STRING,
user_action_time TIMESTAMP(3),
-- 声明user_action_time作为事件时间属性,并允许5S的延迟
WATERMARK FOR user_action_time AS user_action_time - INTERVAL '5' SECOND
) 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);
事件时间字段必须是TIMESTAMP(3)类型,即形如yyyy-MM-dd HH:mm:ss
,如果不是这种形式的数据类型,需要通过定义计算列进行转换。。
如果时间时间的格式类型不是timestamp(3),则需要使用计算列,将其转换为timestamp(3)类型,
如下面的其中两行:
eventTime AS TO_TIMESTAMP(FROM_UNIXTIME(ts, 'yyyy-MM-dd HH:mm:ss')), -- 事件时间
WATERMARK FOR eventTime as eventTime - INTERVAL '5' SECOND -- 在eventTime上定义
CREATE TABLE user_behavior (
user_id BIGINT, -- 用户id
item_id BIGINT, -- 商品id
cat_id BIGINT, -- 品类id
action STRING, -- 用户行为
province INT, -- 用户所在的省份
ts BIGINT, -- 用户行为发生的时间戳
proctime as PROCTIME(), -- 通过计算列产生一个处理时间列
eventTime AS TO_TIMESTAMP(FROM_UNIXTIME(ts, 'yyyy-MM-dd HH:mm:ss')), -- 事件时间
WATERMARK FOR eventTime as eventTime - INTERVAL '5' SECOND -- 在eventTime上定义watermark
) WITH (
'connector.type' = 'kafka', -- 使用 kafka connector
'connector.version' = 'universal', -- kafka 版本,universal 支持 0.11 以上的版本
'connector.topic' = 'user_behavior', -- kafka主题
'connector.startup-mode' = 'earliest-offset', -- 偏移量,从起始 offset 开始读取
'connector.properties.group.id' = 'group1', -- 消费者组
'connector.properties.zookeeper.connect' = 'kms-2:2181,kms-3:2181,kms-4:2181', -- zookeeper 地址
'connector.properties.bootstrap.servers' = 'kms-2:9092,kms-3:9092,kms-4:9092', -- kafka broker 地址
'format.type' = 'json' -- 数据源格式为 json
);
5. 参考资料
Flink从入门到放弃(十二)-企业实战之事件循环驱动型场景(二)
Flink Table API&SQL编程指南之时间属性(3)Flink从入门到放弃(十二)-企业实战之事件循环驱动型场景(二)