为什么Delta Lake似乎会存储大量冗余信息?

问题描述

我刚开始使用三角洲湖泊,因此我的思维模式可能不对-我在问这个问题来验证/驳斥它。

我对三角洲湖泊的理解是,它仅存储数据的增量更改(“三角洲”)。有点像git-每次进行提交时,并不存储代码库的完整快照-提交仅包含所做的更改。 同样,我可以想象,如果我创建一个Delta表,然后尝试使用已包含的所有内容(即“空提交”)“更新”该表,那么我不会期望看到任何新数据会因该更新。

但是,这不是我观察到的不是:这样的更新似乎可以复制现有表。这是怎么回事?对我来说,这似乎不是很“增量”。

(为了可读性,我将替换文件名中的实际UUID值)

# create the data
dataGen = sc._jvm.org.apache.hudi.QuickstartUtils.DataGenerator()
inserts = sc._jvm.org.apache.hudi.QuickstartUtils.convertToStringList(dataGen.generateInserts(200))
df = spark.read.json(spark.sparkContext.parallelize(inserts,2))

delta_base_path = "s3://my-delta-table/test"
(df.write.format("delta")
 .mode("overwrite")
 .save(delta_base_path))
!aws s3 ls --recursive s3://my-delta-table/test

2020-10-19 14:33:21       1622 test/_delta_log/00000000000000000000.json
2020-10-19 14:33:18          0 test/_delta_log_$folder$
2020-10-19 14:33:19      10790 test/part-00000-UUID1-c000.snappy.parquet
2020-10-19 14:33:19      10795 test/part-00001-UUID2-c000.snappy.parquet

然后我使用完全相同的数据集覆盖:

(df.write.format("delta")
 .mode("overwrite")
 .save(delta_base_path))

!aws s3 ls --recursive s3://my-delta-table/test
2020-10-19 14:53:02       1620 test/_delta_log/00000000000000000000.json
2020-10-19 14:53:08        872 test/_delta_log/00000000000000000001.json
2020-10-19 14:53:01          0 test/_delta_log_$folder$
2020-10-19 14:53:07       6906 test/part-00000-UUID1-c000.snappy.parquet
2020-10-19 14:53:01       6906 test/part-00000-UUID3-c000.snappy.parquet
2020-10-19 14:53:07       6956 test/part-00001-UUID2-c000.snappy.parquet
2020-10-19 14:53:01       6956 test/part-00001-UUID4-c000.snappy.parquet

现在有两个part-0part-1,大小完全相同。为何达美不对现有数据进行重复数据删除

解决方法

这不是完全正确的理解-Delta不会自动检查现有数据是否存在重复项-如果您只想存储新数据/更新数据,则需要使用merge operation来检查现有数据,并且那么您可以决定如何处理现有数据-用新数据覆盖,或者忽略它们。

您可以在达美航空网站上或《学习之星》第二版第9章(freely available from Databricks)中找到更多信息