The Linux Foundation Projects
Delta Lake

了解开放表格式

作者:Avril Aysha

本文解释了什么是开放表格式,以及为什么它们是存储表格数据的绝佳选择。

您将了解使用开放表格式与传统数据存储技术的优势。您还将了解不同类型的开放表格式,以及 Delta Lake UniForm、XTable 和 Unity Catalog 等项目如何让您与任何表格式互操作。

开放表格式比将数据存储为 CSV 和 Parquet 等文件格式更高效、更可靠。开放表格式支持 ACID 事务、更高级的数据跳过、时间旅行功能以及其他出色的功能,这些功能将使您的数据工作更快、更安全。

Delta Lake 是一种流行的开放表格式。还有其他开放表格式,如 Apache Iceberg 和 Apache Hudi。

尽管不同的开放表格式之间存在差异,但随着支持互操作性的技术出现,这些差异正变得越来越不重要。Delta Lake UniForm 和 Unity Catalog 等项目正在弥合开放表格式之间的差距。我们将在文章末尾介绍这些项目。

首先,让我们深入了解什么是开放表格式以及它们为何如此出色 😀

什么是开放表格式?

开放表格式是一种用于存储表格数据的开源技术,它构建在现有的文件格式(如 Parquet 和 ORC)之上。开放表格式将您的表格数据存储在文件中,并将元数据(关于您的数据和操作)存储在单独的文件或目录中。此元数据用于启用开放表格式的许多强大功能:更快的查询速度、更可靠的事务和更低的数据损坏风险。

三种主要的开放表格式是 Delta LakeApache HudiApache Iceberg

为什么要使用开放表格式?

开放表格式解决了传统数据湖的性能和可靠性问题。通过将元数据与表格数据一起存储,开放表格式为您提供了强大的功能,例如:

  1. 可靠的 ACID 事务
  2. 高级数据跳过
  3. 时间旅行
  4. 模式强制和演进
  5. 完整的 CRUD 操作

让我们在下面的部分中探讨每个功能。

开放表格式:可靠的 ACID 事务

开放表格式旨在为数据湖生态系统带来 ACID 保证。ACID 事务使您的数据写入更可靠,因此操作不会损坏您的表。“事务”是指任何更改表状态的写入操作。

通过 ACID 事务,您可以确保避免:

  • 中断下游查询的失败部分写入
  • 意外数据损坏
  • 冲突的并发进程或数据版本
  • 意外数据丢失

Delta Lake 与数据湖一文中阅读更多内容。

开放表格式:高级数据跳过

开放表格式比 Parquet 和 CSV 等文件格式提供更高级的数据跳过。由于它们将元数据存储在集中式元数据目录中,查询引擎可以轻松找到选择性查询的相关数据。

Delta Lake 通过 (1) 集中式事务日志中高效的元数据存储和 (2) 通过 Z-orderingLiquid Clustering 优化的数据布局来支持高级数据跳过。这些策略将使您的查询运行得更快。

在 [数据跳过指南] (#add-when-live) 中阅读更多内容。

开放表格式:时间旅行

开放表格式支持时间旅行。这意味着您可以轻松检查数据集的早期版本,并在需要时恢复到这些版本。

Delta Lake 通过其事务日志支持数据版本控制。您对数据所做的所有更改都记录在此日志中。这意味着您可以轻松查看以前的版本,并在需要时纠正意外错误。

您可以像这样加载 Delta 表的特定版本:

spark.read.format("delta").option("versionAsOf", version).load("path/to/delta")

Delta Lake 时间旅行文章中阅读更多内容。

开放表格式:模式强制和演进

为了确保数据一致性并避免损坏,您通常希望确保新数据与现有模式匹配。这称为模式强制。

许多标准文件格式(如 Parquet 和 CSV)默认不支持模式强制。这意味着您可以轻松地将具有不同模式的数据写入现有的 Parquet 数据湖,例如。这将在尝试读取数据时导致下游问题。

开放表格式默认内置模式强制。这可以防止您意外损坏数据。

让我们看看 Delta Lake 中的实际操作。

创建一个包含两列的 Delta 表:first_nameage

df = spark.createDataFrame([("bob", 47), ("li", 23), ("leonard", 51)]).toDF(
    "first_name", "age"
)

df.write.format("delta").save("tmp/fun_people")

现在,尝试将具有不同模式的数据写入此表

df = spark.createDataFrame([("frank", 68, "usa"), ("jordana", 26, "brasil")]).toDF(
    "first_name", "age", "country"
)

df.write.format("delta").mode("append").save("tmp/fun_people")

此操作将因 AnalysisException 而报错。

Delta Lake 默认不允许您追加具有不匹配模式的数据。在您有意更新模式的情况下,您可以使用 mergeSchema 选项。

df.write.option("mergeSchema", "true").mode("append").format("delta").save(
    "tmp/fun_people"
)

阅读Delta Lake 模式强制Delta Lake 模式演进文章以了解更多信息。

开放表格式:完整的 CRUD 操作

常规的 Parquet 文件是不可变的。更改 Parquet 文件的唯一方法是完全覆盖它。这是一个特性:它可以防止您意外损坏数据。

像 Delta Lake 这样的开放表格式比常规的 Parquet 文件为您提供更高的可靠性和更大的灵活性。您可以使用开放表格式对数据子集执行 CRUD(创建、读取、更新、删除)操作。

例如,您可以使用 Delta Lake replaceWhere 操作选择性地覆盖表中的特定行:

(
    df.write.format("delta")
    .option("replaceWhere", "number > 2")
    .mode("overwrite")
    .save("tmp/my_data")
)

开放表格式将这类部分数据更新视为“逻辑操作”。删除或覆盖操作只是更改事务日志中的标记,以指向新行或新列。实际数据不受影响。这样,您就可以安全地对数据进行部分更改,而无需执行昂贵的重写。

我可以一起使用不同的开放表格式吗?

是的,您可以一起使用不同的开放表格式,但这需要仔细规划。Delta Lake、Apache Iceberg 和 Apache Hudi 等开放表格式最初旨在独立管理数据集。每种格式都有自己的元数据结构、事务管理和 API。这可能会使互操作性变得棘手。

Delta Lake UniFormApache XTable 等项目正在努力统一开放表格式的工作流程。例如,您可以使用 Delta Lake 进行 您的 ETL 工作负载,然后使用 UniForm 将您的数据作为 Iceberg 表读取到下游 BI 和分析系统中。

Unity Catalog 是另一个致力于改进开放表格式互操作性的项目。通过 Unity Catalog,您可以存储、管理和访问 Delta Lake 和 Iceberg 格式的表格数据。

阅读统一开放表格式文章以了解更多信息。

我可以将开放表格式转换为 Parquet 等文件格式吗?

是的,在大多数情况下,您可以将以开放表格式(例如 Delta Lake)存储的表转换为其底层文件格式(例如 Parquet)。

例如,要将 Delta 表转换为具有 Hive 样式分区的 Parquet 数据湖,您只需:

  1. 清理任何陈旧文件
  2. 删除事务日志目录

从纯性能角度来看,如果可以避免,通常不应从 Delta Lake 转换为 Parquet。Delta Lake 几乎总是更快、更可靠。仅在您确定不再需要版本控制或事务管理等功能时才这样做。

我应该何时使用开放表格式?

开放表格式几乎总是比使用 Parquet、CSV 或 JSON 等文件格式的数据湖更快、更安全、更对开发人员友好。像 Delta Lake 这样的开放表格式可能是您的绝佳选择,因为它们:

  • 支持事务和模式强制,因此损坏表的可能性大大降低。
  • 将文件元数据抽象到事务日志中,并支持高级集群和数据跳过,因此您可以更快地运行查询。
  • 使执行常见数据操作(如删除列、重命名列、删除行和 DML 操作)变得容易。

如果您正在生产中运行重要的表格数据工作流,开放表格式可能是您的最佳选择。

LinkedIn 上关注我们的作者