flink sql 数据乱序原因分析
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条件和主表主键字段做主键