三角洲湖:我们不再需要时间分区来完全重新处理的表了吗



目标

假设您正在ETL的帮助下构建数据湖和星模式。存储格式为三角洲湖。ETL的职责之一是构建缓慢变化维度(SCD(表(累积状态(。这意味着,ETL每天都会为每个SCD表读取完整表的状态,应用更新并将其保存回(完全覆盖(。

问题

我们在团队中讨论的一个问题是:我们是否应该向SCD(完全覆盖(表添加时间分区?意味着,我应该将最新(完整(的表状态保存到SOME_DIMENSION/还是SOME_DIMENSION/YEAR=2020/MONTH=12/DAY=04/

注意事项

一方面,三角洲湖具备了所有必需的功能:时间旅行;酸。当它覆盖整个表时,就会发生逻辑删除,并且您仍然可以查询旧版本并回滚到它们。因此,德尔塔湖几乎为您管理时间分区,代码变得更简单。

另一方面,我说";几乎";因为IMHO时间旅行&ACID不能覆盖100%的用例。它还不知道到达时间。例如:

示例(当您需要时间分区时(

BA团队报告称,SOME_FACT/YEAR=2019/MONTH=07/DAY=15数据已损坏(在任何情况下都必须使用时间分区存储事实,因为数据是按到达时间处理的(。为了在DEV/TEST环境中重现问题,您需要1个事实表原始输入和10个SCD表。

有了事实,一切都很简单,因为您在Data Lake中有原始输入。但是,对于增量状态(SCD表(,情况会变得复杂——如何获得处理SOME_FACT/YEAR=2019/MONTH=07/DAY=15的时间点的10个SCD表的状态?如何自动做到这一点

更为复杂的是,您的环境可能会经历一系列错误修复和历史重新处理。意味着2019-07年的数据可能在2020年的某个地方被重新处理。Delta Lake允许您仅根据处理或版本号进行回滚。所以你实际上不知道应该使用哪个版本。

另一方面,对于日期分区,您总是可以确保SOME_FACT/YEAR=2019/MONTH=07/DAY=15是在SOME_DIMENSION/YEAR=2019/MONTH=07/DAY=15上计算的。

这取决于情况,我认为它有点复杂。

一些上下文优先-德尔塔为您提供的时间旅行仅限于当前提交历史记录,默认情况下为30天。如果您正在进行优化,则时间可能会明显缩短(默认为7天(。此外,您实际上可以查询特定时间的Delta表,不仅是版本,而且由于上述限制(除非您愿意为存储非常长的提交历史记录支付性能和财务成本(,从长远来看,这是没有用的。

这就是为什么现在一种非常常见的数据湖架构是奖章表方法(青铜->银->金(。理想情况下,我想将原始输入存储在"青铜"层中,在银层中有一个完整的历史视角(已经是干净的、经过验证的、最好的真相来源,但需要完整的历史(,并直接从";金色";表。

这将避免由于额外的分区而增加查询SCD的复杂性,同时使您可以选择";返回";如果需要的话,将其转移到银层。但这始终是一个权衡决定——在任何情况下,都不要依赖Delta进行长期版本控制。

最新更新