0

客观的

假设您在 ETL 的帮助下构建数据湖和星型模式。存储格式为 Delta Lake。ETL 的职责之一是构建渐变维度 (SCD) 表(累积状态)。这意味着对于每个 SCD 表,ETL 每天都会读取整个表的状态,应用更新并将它们保存回来(完全覆盖)。

问题

我们团队内部争论的一个问题:我们应该将时间分区添加到 SCD(完全覆盖)表吗?意思是,我应该将最新的(完整)表状态保存到SOME_DIMENSION/还是保存到SOME_DIMENSION/YEAR=2020/MONTH=12/DAY=04/

注意事项

一方面,Delta Lake 具有所有必需的功能:时间旅行和 ACID。当它覆盖整个表时,会发生逻辑删除,您仍然可以查询旧版本并回滚到它们。所以 Delta Lake 几乎为你管理时间分区,代码变得更简单。

另一方面,我说“几乎”是因为恕我直言时间旅行和酸不能覆盖 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.

4

1 回答 1

1

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

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

这就是为什么现在一个非常常见的数据湖架构是奖章表方法(青铜->白银->黄金)。理想情况下,我想将原始输入存储在“青铜”层中,在银层中有一个完整的历史视角(已经干净、经过验证、最好的事实来源,但需要完整的历史),并消耗当前直接来自“黄金”表的版本。

这将避免由于附加分区而增加查询 SCD 的复杂性,同时让您可以在需要时选择“返回”到银层。但这始终是一个权衡决定——无论如何,不​​要依赖 Delta 进行长期版本控制。

于 2020-12-04T22:58:03.797 回答