Flink SQL中Timestamp使用的坑

flink版本为1.10。

flink sql消费kafka消息,表定义为

CREATE TABLE start_log_source( 
   mid_id VARCHAR,  
   user_id INT,  
   ... 
   app_time TIMESTAMP, -- 13位的时间戳(1587975971431)
   WATERMARK FOR app_time AS app_time- INTERVAL '5' SECOND   -- 在ts上定义5 秒延迟的 watermark
) WITH ( 
    'connector.type' = 'kafka',  -- 使用 kafka connector
    'connector.version' = 'universal',  -- kafka 版本,universal 支持 0.11 以上的版本
    'connector.topic' = 'start_log',  -- kafka topic
	'connector.properties.group.id' = 'start_log_group',
    'connector.startup-mode' = 'earliest-offset',  -- 从起始 offset 开始读取
    'connector.properties.zookeeper.connect' = '192.168.1.109:2181',  -- zookeeper 地址
    'connector.properties.bootstrap.servers' = '192.168.1.109:9092',  -- kafka broker 地址
    'format.type' = 'json'  -- 数据源格式为 json  
);

以上代码运行时报错,大概信息是转换错误,查阅文档后发现应该是app_time定义有问题。如果app_time类型定义为TIMESTAMP,那它的值应该为2020-04-06T16:26:11类似的格式。
进一步查询发现watermark的一些使用要求:
WATERMARK 定义了表的事件时间属性,其形式为 WATERMARK FOR rowtime_column_name AS watermark_strategy_expression 。
rowtime_column_name 把一个现有的列定义为一个为表标记事件时间的属性。该列的类型必须为 TIMESTAMP(3),且是 schema 中的顶层列,它也可以是一个计算列。

但是app_time实际数据格式为13位的时间戳,也就是毫秒级的时间戳,TIMESTAMP(3)是秒级时间戳,则必须经过转换才行。刚开始使用TO_TIMESTAMP内置函数,但是它不支持数值型时间戳值转换为TIMESTAMP。经过一番折腾,终于成功,SQL如下:

CREATE TABLE start_log_source( 
   mid_id VARCHAR,  
   user_id INT,  
   ... 
   app_time BIGINT, -- 13位的时间戳(1587975971431)
   ts AS TO_TIMESTAMP(FROM_UNIXTIME(app_time / 1000, 'yyyy-MM-dd HH:mm:ss')), -- 定义事件时间
   WATERMARK FOR ts AS ts - INTERVAL '5' SECOND   -- 在ts上定义5 秒延迟的 watermark
) WITH ( 
    'connector.type' = 'kafka',  -- 使用 kafka connector
    'connector.version' = 'universal',  -- kafka 版本,universal 支持 0.11 以上的版本
    'connector.topic' = 'start_log',  -- kafka topic
	'connector.properties.group.id' = 'start_log_group',
    'connector.startup-mode' = 'earliest-offset',  -- 从起始 offset 开始读取
    'connector.properties.zookeeper.connect' = '192.168.1.109:2181',  -- zookeeper 地址
    'connector.properties.bootstrap.servers' = '192.168.1.109:9092',  -- kafka broker 地址
    'format.type' = 'json'  -- 数据源格式为 json  
);

你可能感兴趣的:(flink)