flink sql 数据乱序或数据被覆盖

本文分析了Flink SQL多表左连接时数据乱序的问题,主要源于join操作产生的中间状态分区依赖和不稳定的id值。解决方法包括使用子查询和复合主键,确保数据一致性。关键词:Flink, left join, 数据乱序, 主键唯一, 解决策略
摘要由CSDN通过智能技术生成

1、多表left join 乱序

1.1、flink sql 如下:

sink to pg 表的主键:id

select c1.id,c1.name1,c2.name2,c3.name3,c1.num 
from flink_multilist_left_join_check1 c1
left join flink_multilist_left_join_check2 c2 on c2.id = c1.id and c2.deleted is false
left join flink_multilist_left_join_check3 c3 on c3.id = c2.id and c3.deleted is false
where c1.deleted is false

结论:sink to pg 表数据漏数
原因:

1、flink sql 中一个join会生成一个中间结果状态;
2、数据分发到下游是通过left join 条件hashcode分发到下游分区;
3、当left join 条件字段值发生改变(如:id = 2 更新 id = null 或相反的情况)然后id = null 的数据分发可能与id = 2 的数据分发的分区不同,当消费分区数据时因延时或前提原因导致 id = null 的先消费到,id  = 2 的记录没有被更新为null, 如此就造成下游数据更新失败,即数据乱序
4、同 3 , 当更新 id = null 的记录先被消费到,之后消费到id = 2 的记录,消费 id = 2 (删除) 的记录, 此时id = null 这条记录就会被删除 ,即漏数

原因总结:sink to pg 表的记录主键不唯一

解决方法:
1、sql 改为子查询:c2 left join c3 先关联查询后在与c1关联查询,同时新增记录主键:要另外加上join条件字段做主键
2、外部的sql也要新增join条件字段做主键 , 同时看情况定是否要把子查询中的主键也作为外部主键的一部分

2、多表与主表关联数据乱序

select c1.id,c1.name1,c2.name2,c3.name3,c1.num 
from flink_multilist_left_join_check1 c1
left join flink_multilist_left_join_check2 c2 on c2.id = c1.id and c2.deleted is false
left join flink_multilist_left_join_check3 c3 on c3.id = c1.id and c3.deleted is false
where c1.deleted is false

原因同上
解决方案:
sink的表主键要使用join条件和主表主键字段做主键

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FlinkSQL中的数据源可以通过使用connector来定义。在给出的引用中,有两个例子可以作为参考。 引用[1]中的例子展示了如何使用`datagen` connector来创建一个临时表,并通过`generateRowUdtf`函数生成新的行。具体步骤如下: 1. 创建一个临时表`test_insert`,并使用`datagen` connector作为数据源。可以通过设置参数来控制生成速率和字段的属性。 ```sql CREATE TEMPORARY table test_insert( id2 String ) WITH( 'connector' = 'datagen', 'rows-per-second'='100', 'fields.id2.kind'='random', 'fields.id2.length'='8' ); ``` 2. 创建一个系统函数`generateRowUdtf`,并将其指定为`lateral table`的参数。这个函数可以根据输入的参数生成新的行。 ```sql CREATE TEMPORARY SYSTEM FUNCTION generateRowUdtf AS 'udf2.generateRowUdtf'; ``` 3. 使用`lateral table`和`generateRowUdtf`函数来生成新的行,并将其与`test_insert`表进行连接操作。 ```sql insert into xxx SELECT T.id, T.data1, T.data2, T.data4 FROM test_insert AS S left join lateral table(generateRowUdtf(id2)) AS T(id,data1,data2,data4) on true; ``` 引用中的例子展示了如何使用自定义的UDF作为数据源。具体步骤如下: 1. 创建一个自定义的connector,类似于`data-gen` connector。这个connector可以根据你的需求生成数据。 2. 创建一个UDF函数,该函数可以根据输入参数生成多列输出。 3. 使用自定义的connector和UDF函数来生成数据。 以上是两个例子,你可以根据你的需求选择适合的方法来定义FlinkSQL中的数据源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值