【发布时间】:2020-12-05 06:58:03
【问题描述】:
目标
假设您在 ETL 的帮助下构建数据湖和星型模式。存储格式为 Delta Lake。 ETL 的职责之一是构建渐变维度 (SCD) 表(累积状态)。这意味着,对于每个 SCD 表,ETL 每天都会读取整个表的状态,应用更新并将它们保存回来(完全覆盖)。
问题
我们在团队中争论的一个问题是:我们是否应该向 SCD(完全覆盖)表添加时间分区?意思是,我应该将最新的(完整)表状态保存到SOME_DIMENSION/ 还是SOME_DIMENSION/YEAR=2020/MONTH=12/DAY=04/?
注意事项
一方面,Delta Lake 具有所有必需的功能:时间旅行和 ACID。当它覆盖整个表时,会发生逻辑删除,您仍然可以查询旧版本并回滚到它们。所以Delta Lake几乎为你管理时间分区,代码变得更简单了。
另一方面,我说“几乎”是因为恕我直言,时间旅行和 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 上计算得出的。
【问题讨论】:
标签: apache-spark architecture etl delta-lake data-lake