分析Iceberg合并任务解决数据冲突

本文分析了Iceberg在合并小文件过程中如何处理数据冲突。通过行级删除记录和equality delete,Iceberg能够识别并解决不同快照间的数据冲突。在数据合并时,如果遇到数据修改,Iceberg使用sequenceNumber和parquet文件的min/max值判断数据的有效性。通过设置USE_STARTING_SEQUENCE_NUMBER属性,可以避免某些场景下的数据冲突,确保数据一致性。
摘要由CSDN通过智能技术生成

作者:吴文池

背景

iceberg提供合并小文件功能,可以按照用户的配置文件,把多个符合配置的小文件合并成多个大文件。该流程主要是对源数据做了一次复制。

但在实际生产环境中,数据是一直在变化的,有可能会出现这种情况:在还未完成数据合并任务时,对之前的数据做出了修改,这就导致正在合并的数据与新数据可能会产生冲突。

那么iceberg是如何处理这种数据冲突的呢?

iceberg行级删除

iceberg的行级修改主要是通过行级删除记录再加上数据记录实现的,所以下面先说一下iceberg行级删除的实现。

iceberg行级删除实现概要

iceberg的行级更新和删除,主要是通过增加delete记录做到的。iceberg总共有两种delete类型,一种是position delete,一种是equality delete,主要区别是在于该数据的插入和修改操作是否在同一个checkpoint内。此次分析的冲突场景主要是不同快照间的,所以以下说明都以equality delete为背景,简单说下流程(非upsert模式)。

先在 writer 中设置 equalityFieldColumns :

DataStreamSink append = FlinkSink.forRowData(input)
.tableLoader(tableLoader)
.overwrite(false)
.distributionMode(DistributionMode.HASH)
.equalityFieldColumns(Lists.newArrayList(“column1”, “column2”))
.append();
设置好之后,writer就会根据设置的列对数据做写入,如果是插入的数据,则写为数据记录,如果是删除数据,则写为删除记录(非upsert模式):

case INSERT:
case UPDATE_AFTER:
if (upsert) {
writer.delete(row);
}
writer.write(row);
break;
case UPDATE_BEFORE:
if (upsert) {
break; // UPDATE_BEFORE is not necessary for UPDATE, we do nothing to prevent delete one row twice
}
writer.delete(row);
break;
case DELETE:
writer.delete(row);
break;
在读取数据的时候,会根据数据生成的顺序(即sequenceNumber),判断该数据记录是否有对应的删除记录,如果有,则认为该数据已经被删除,如果没有,则认为该数据依然存在。

应用删除记录的判断条件

i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值