请教一个 Flink SQL 的问题,解决了星巴克感谢

查看 194|回复 28
作者:kerie   
我是一个 Flink 小白,最近有一个监控需求,想使用 Flink SQL 实现,但很多概念还没搞清楚,遇到一个问题卡壳了,在论坛里寻 Flink 大佬指点一二,解决了送一杯星巴克作为感谢!
Flink SQL 官网用客户(customer)和订单(order)举例,但都每分钟统计流表每个客户订单的数量。我的需求是每分钟统计维表全量每个客户订单的数量,也就是就算这一分钟某个客户没有下单,也需要统计一个 0 出来,用于做监控报警。
为了不暴露业务需求,调整为客户和订单的场景,如果有不恰当的地方还请指出,我再补充,SQL 如下:
CREATE TEMPORARY TABLE customers (
    id INT,
    name STRING
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://....'
);
CREATE TEMPORARY TABLE orders (
    order_id     STRING,
    customer_id  INT,
    order_time   TIMESTAMP(3),
    WATERMARK FOR order_time AS order_time - INTERVAL '15' SECOND
) WITH (
    'connector' = 'kafka',
    'topic' = '...'
);
CREATE TEMPORARY VIEW order_per_minute AS
SELECT
    customer_id,
    count(*) as cnt,
    TUMBLE_END(order_time, INTERVAL '1' MINUTE) AS window_end
FROM orders
GROUP BY customer_id, TUMBLE(tstamp, INTERVAL '1' MINUTE);
INSERT INTO destination
SELECT
    COALESCE(window_end, CURRENT_TIMESTAMP),
    customer_id,
    COALESCE(cnt, 0),
FROM
    customers LEFT JOIN order_per_minute
        ON customers.id = order_per_minute.customer_id;
实际执行上面的代码有问题,比如说有 3 个客户 c1/c2/c3 ,但只有 2 个客户 c1/c2 每分钟都下单,
第一次执行结果是对的:
10:01, c1, 19  
10:01, c2, 32  
10:01, c3, 0
随后每分钟的数据,就会少掉 c3 的结果:
10:02, c1, 18  
10:02, c2, 22 // c3 没有输出
10:03, c1, 18  
10:03, c2, 22 // c3 没有输出
我也不清楚 Flink SQL 能否这么用吗,还是得用 DataStream API 解决?请论坛的 Flink 大佬帮忙看一下,感谢!
为了防止 customer 、order 场景误导,这里说一下实际场景:
实际是要监控 IoT 设备的数据推送,IoT 设备全量表是预先初始化好的,保存在 MySQL 数据表; IoT 数据推送是一个 kafka 流消息,理论上每个 IoT 设备每秒都有数据。需求是监控哪些 IoT 设备数据是中断或缺失的。

flink, SQL, order_time

sijue   
为了防止 customer 、order 场景误导,这里说一下实际场景:
实际是要监控 IoT 设备的数据推送,IoT 设备全量表是预先初始化好的,保存在 MySQL 数据表; IoT 数据推送是一个 kafka 流消息,理论上每个 IoT 设备每秒都有数据。需求是监控哪些 IoT 设备数据是中断或缺失的。
sijue   
上面 left join 是 regural join ,没有数据可能是因为 customer 中 c3 数据在 10:02 和 10:03 没有记录,建议使用 lookup join
liprais   
补充:维表 join 常用 look up join ,参考: https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/dev/table/sql/queries/joins/
kerie
OP
  
你应该用用户表左关联
kerie
OP
  
@sijue 对的,上面的 left join 是 regular join ,没有数据是因为 customer 表没有时间戳信息,它只是一个全量客户的表,没有带时间戳信息。
lookup join 有上面一样的问题,不能输出没有 order 数据的 customer 统计。
liprais   
@liprais 我用的 customers left join order_per_minute ,但不能统计出没有 order 的 customer
kerie
OP
  
"If a table function call returns an empty result, the corresponding outer row is preserved, and the result padded with null values. Currently, a left outer join against a lateral table requires a TRUE literal in the ON clause."
sijue   
@liprais 这里的`table function`指的是 udf (用户自定义函数)吗,不使用 udf 可以吗
t3zb2xzvjm4yvmn   
1.有个治标的方式:维表初始化目前存量用户数据,订单数为 0 ,订单表一般是注册之后才能下单;
2.有个疑问点:有订单,用户表和订单表都会存数据,是否存在订单数据比用户数据迟到的点
您需要登录后才可以回帖 登录 | 立即注册

返回顶部