flink sql中指定时间字段

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 SQL之维表join - 知乎

Flink从入门到放弃(十二)-企业实战之事件循环驱动型场景(二)

Flink Table API&SQL编程指南之时间属性(3)Flink从入门到放弃(十二)-企业实战之事件循环驱动型场景(二)

  • 9
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以通过 Flink SQL 的 `PARTITION BY` 子句来指定分区字段,然后使用 FlinkKafka Producer 将数据发送到 Kafka 。下面是一个示例代码: ```java // 创建 Flink Table Environment StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); StreamTableEnvironment tEnv = StreamTableEnvironment.create(env); // 创建 Kafka Producer 配置 Properties kafkaProps = new Properties(); kafkaProps.setProperty("bootstrap.servers", "localhost:9092"); // 定义输入数据源 String sourceDDL = "CREATE TABLE source_table (id INT, name STRING, event_time TIMESTAMP(3), WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND) WITH (...)"; tEnv.executeSql(sourceDDL); // 定义输出数据源 String sinkDDL = "CREATE TABLE sink_table (id INT, name STRING) WITH ('connector' = 'kafka', 'topic' = 'output-topic', 'properties' = '" + kafkaProps.toString() + "', 'format' = 'json')"; tEnv.executeSql(sinkDDL); // 执行 SQL 查询并写入 Kafka String sql = "INSERT INTO sink_table SELECT id, name FROM source_table PARTITION BY id"; tEnv.executeSql(sql); ``` 在上面的代码,我们首先创建了一个 Flink Table Environment,并且定义了 Kafka Producer 的配置。然后,我们使用 Flink SQL 创建了输入和输出表。输入表包括一个 `event_time` 字段,我们使用它来定义 watermark。输出表是一个 Kafka topic,我们使用 `PARTITION BY` 子句按照 `id` 字段进行分区。最后,我们执行了 SQL 查询并将结果写入 Kafka topic。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值