您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
什么是 Flink SQL 解决不了的问题?
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
什么是 Flink SQL 解决不了的问题?
1669877492_m
2024-07-05
IP归属:北京
64浏览
# 简介 在实时数据开发过程中,大家经常会用 Flink SQL 或者 Flink DataStream API 来做数据加工。通常情况下选用2者都能加工出想要的数据,但是总会有 Flink SQL 覆盖不了的问题,但 SQL 的易用性又难以让人释怀。所以有些场景在使用 FLink SQL 开始就与需要额外注意,下面就介绍一种多表关联时存在部分列更新(partial Update)场景,在 DataStream API 和 Flink SQL 开发时都容易忽视的情况而导致的问题。为了简化问题描述,采用了Flink SQL 来阐述此类问题。 # 场景介绍 多表关联时表 A 关联表 B, 表 A 具有pk1, field1, field2, field3字段,表 B 具有 pk2, field4, field5, field6 字段,表 A 通过 pk1 关联表B pk2。使用 Flink SQL 会如下实现: ```SQL CREATE TABLE jdq_source( pk1 INT, field1 STIRNG, field2 STIRNG, field3 STIRNG, PRIMARY KEY(pk1) NOT ENFORCED ) WITH(...); CREATE TABLE sr_sink( pk1 INT, field1 STRING, field2 STRING, field3 STRING, field4 STRING, field5 STRING, field6 STRING, PRIMARY KEY(pk2) NOT ENFORCED ) WITH (...); INSERT INTO C SELECT A.pk1,A.field1,A.field2,A.field3,B.pk2,B.field4,B.field5,B.field6 FROM jdq_source A INNER JOIN sr_sink B ON A.pk1 = B.pk2; ``` 上述实例中有明显特征:使用了Join 关联, 且需要注意的是写入的数据库 sink 是 StarRocks。StarRocks 存在如下特性:当表是主键表时是不支持部分列更新( Partial Update)的,实际上大部分时候大家都用的是主键表。 然后在一个SQL查询数据的接口就遇到了如下问题:每次从接口查询返回的结果都不稳定,同样的查询条件不同时机返回的结果不一样。SQL查询语句如下: ```SQL select C.field1,C.field2,C.field3 FROM C group by field1,field2,field3; ``` 为什么SQL查询的结果会不一致呢?起初排查原因发现 group by 返回结果有多条,而在SQL 中也没有使用 order by 对数据进行排序,所以导致了结果不稳定。后又排查为什么会出现多条结果呢?于是怀疑 field1, field2, field3 有不符合预期的数据。如: 20240530, 2, 3 20240530, 2, null 20240531, 2, 4 其中第2条是多余的,不应该出现。结果发现可能是如下原因导致的:这3个字段 filed1, field2, filed3 在StarRocks数据库中会一直在变化,不停的写入新值。导致 SQL 查询时可以查到 field3 为 null 的数据。 为什么field3为不断变化呢?究其原因是:StarRocks 主键表不支持部分列更新(Partial Update)。当field3 为null时,同样会被写入 StarRocks。我们在通过JDQ读取表A field1, field2, field3 数据给表C写入数据时,当JDQ 消息队列中表A的记录存在乱序场景且field3 字段可能为null时,最终写入StarRocks的field3 字段会出现时而为null,时而不为null。 所以SQL查询接口中 group by的结果会出现不稳定。 # 总结 1. 为什么在开发的时候当时没有发现 StarRocks 主键表这个问题呢?原因:1. 大家所关注的部分列更新,多数是关注insert into table_C(field1, field2, field3) 中不包含的字段field4,field5...等被更新为null,而当前场景是会把 field3 为null的值也写入SR数据库中,这不是我们期望的结果。2.表A作为主表,通常不会出现开始field3有值后来又没有值(null)的场景。出现这个现象大概率是因为上游JDQ消息队列中的数据乱序了,导致field3 为null的后出现了。而这种问题又比较难发现。 2. 什么情况下会出现此类问题呢?写入的数据库不支持部分列更新场景时会出现。如StarRocks, Doris。因为MySQL, ES,ClickHouse的部分表引擎支持部分列更新,所以在MySQL, ES,ClickHouse中不会出现。 3. 同理在 DataStream API 中如果表 A,表 B 关联后的数据直接写入StarRocks 的话,也会出现此类问题。 以上这个问题在 Flink SQL 中无法解决,在 Flink DataStream API 中可以模拟部分列更新来避免此类问题。具体方法:在DatStream 任务中增加一个MapState, 用来在新数据到来时从MapState拿出缓存的数据,并和新到来的数据进行合并,来实现部分列更新功能,最后再写入 StarRocks。 虽然问题不是Flink SQL导致的,但是上面的问题可以通过Flink DataStream API来规避。
上一篇:托寄物智能识别——大模型在京东快递物流场景中的应用与落地
下一篇:使用mybatis切片实现数据权限控制
1669877492_m
文章数
3
阅读量
207
作者其他文章
01
Flink State 状态原理解析
一、Flink State 概念State 用于记录 Flink 应用在运行过程中,算子的中间计算结果或者元数据信息。运行中的 Flink 应用如果需要上次计算结果进行处理的,则需要使用状态存储中间计算结果。如 Join、窗口聚合场景。Flink 应用运行中会保存状态信息到 State 对象实例中,State 对象实例通过 StateBackend 实现将相关数据存储到 FS 文件系统或者 Roc
01
什么是 Flink SQL 解决不了的问题?
简介在实时数据开发过程中,大家经常会用 Flink SQL 或者 Flink DataStream API 来做数据加工。通常情况下选用2者都能加工出想要的数据,但是总会有 Flink SQL 覆盖不了的问题,但 SQL 的易用性又难以让人释怀。所以有些场景在使用 FLink SQL 开始就与需要额外注意,下面就介绍一种多表关联时存在部分列更新(partial Update)场景,在 DataSt
01
基于图遍历的Flink任务画布模式下零代码开发实现方案
前言提交一个DataSteam 的 Flink应用,需要经过 StreamGraph、JobGraph、ExecutionGraph 三个阶段的转换生成可成执行的有向无环图(DAG),并在 Flink 集群上运行。而提交一个 Flink SQL 应用,其执行流程也类似,只是多了一步使用 flink-table-planer 模块从SQL转换成 StreamGraph 的过程。以下是利用Flink的
1669877492_m
文章数
3
阅读量
207
作者其他文章
01
Flink State 状态原理解析
01
基于图遍历的Flink任务画布模式下零代码开发实现方案
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号