通用格式 (UniForm)

Delta通用格式(UniForm)允许您使用Iceberg和Hudi客户端读取Delta表。

UniForm 利用了Delta Lake、Iceberg和Hudi都由Parquet数据文件和元数据层组成这一事实。UniForm会异步自动生成Iceberg元数据,使Iceberg客户端能够像读取Iceberg或Hudi表一样读取Delta表。启用UniForm后,Delta写入开销可以忽略不计,因为元数据转换和事务是在Delta提交后异步进行的。

数据文件的单一副本可提供给所有格式的客户端访问。

要求

要启用UniForm,您必须满足以下要求:

统一Iceberg

  • 该表必须启用列映射功能。请参阅Delta列映射

  • Delta表必须满足minReaderVersion >= 2且minWriterVersion >= 7。

  • 对该表的写入操作必须使用Delta Lake 3.1或更高版本。

  • 必须将Hive Metastore (HMS)配置为目录。有关如何配置Apache Spark以使用Hive Metastore,请参阅HMS文档

统一Hudi (预览版)

  • 对表的写入操作必须使用Delta Lake 3.2或更高版本。

启用Delta Lake UniForm

重要

启用Delta UniForm Iceberg需要Delta表功能IcebergCompatV2,这是一个写入协议功能。只有支持此表功能的客户端才能写入已启用的表。您必须使用Delta Lake 3.1或更高版本来写入启用了此功能的Delta表。

启用Delta UniForm Iceberg需要在Spark shell中提供"delta-iceberg"包:–packages io.delta:io.delta:delta-iceberg_2.12:

启用Delta UniForm Hudi功能需要向Spark shell提供"delta-hudi"包:–packages io.delta:io.delta:delta-hudi_2.12:

以下表格属性支持为Iceberg启用UniForm功能。

'delta.enableIcebergCompatV2' = 'true'
'delta.universalFormat.enabledFormats' = 'iceberg'

以下表格属性支持为Hudi启用UniForm功能。

'delta.universalFormat.enabledFormats' = 'hudi'

以下表格属性支持UniForm对两者的兼容。

'delta.enableIcebergCompatV2' = 'true'
'delta.universalFormat.enabledFormats' = 'iceberg,hudi'

要使用UniForm,您还必须启用列映射。在创建表时会自动设置,如下例所示:

CREATE TABLE T(c1 INT) USING DELTA TBLPROPERTIES(
  'delta.enableIcebergCompatV2' = 'true',
  'delta.universalFormat.enabledFormats' = 'iceberg');

在 Delta 3.3 及以上版本中,您可以使用以下语法在现有表上启用或升级 UniForm Iceberg:

ALTER TABLE table_name SET TBLPROPERTIES(
  'delta.enableIcebergCompatV2' = 'true',
  'delta.universalFormat.enabledFormats' = 'iceberg');

你也可以使用REORG来启用UniForm Iceberg并重写底层数据文件,如下例所示:

REORG TABLE table_name APPLY (UPGRADE UNIFORM(ICEBERG_COMPAT_VERSION=2));

在以下任一情况为真时使用REORG:

  • 您的表已启用删除向量。

  • 您之前启用了UniForm Iceberg的IcebergCompatV1版本。

  • 您需要从不支持Hive风格Parquet文件的Iceberg引擎读取数据,例如Athena或Redshift。

您可以使用以下语法在现有表上启用UniForm Hudi:

ALTER TABLE table_name SET TBLPROPERTIES ('delta.universalFormat.enabledFormats' = 'hudi');

注意

该语法要求在Delta 3.1上运行前,需先在表上启用Delta列映射功能。此语法也可用于从IcbergCompatV1版本升级。它可能会重写现有文件使其兼容Iceberg格式,并自动禁用和清除表中的删除向量。

重要

首次启用UniForm时,系统会开始异步生成元数据。在外部客户端能够使用Iceberg或Hudi查询表之前,此任务必须完成。请参阅检查Iceberg/Hudi元数据生成状态

警告

您可以通过取消设置表属性delta.universalFormat.enabledFormats来关闭UniForm功能。但请注意,一旦启用列映射就无法关闭,且升级Delta Lake读写器协议版本的操作不可逆。

参见限制

UniForm何时生成元数据?

Delta Lake 在完成写入事务后,会使用相同的计算资源异步触发 Iceberg/Hudi 元数据的生成。

Iceberg/Hudi的写入延迟可能明显高于Delta Lake。频繁提交的Delta表可能会将多个Delta提交合并为单个Iceberg/Hudi提交。

Delta Lake确保在单个集群中,任何时刻每个格式只有一个元数据生成过程在进行。那些会触发第二个并发元数据生成过程的提交虽然能成功提交到Delta,但不会触发异步元数据生成。这可以防止频繁提交工作负载(提交间隔在几秒到几分钟之间)时出现元数据生成的级联延迟问题。

检查Iceberg/Hudi元数据生成状态

UniForm向Iceberg/Hudi表元数据添加以下属性以跟踪元数据生成状态:

表属性

描述

converted_delta_version

成功生成元数据的最新版本的Delta表。

converted_delta_timestamp

成功生成元数据的最新Delta提交的时间戳。

有关如何在Delta Lake之外查看表属性,请参阅您的Iceberg/Hudi读取器客户端文档。对于Apache Spark,您可以使用以下语法查看这些属性:

SHOW TBLPROPERTIES <table-name>;

在Apache Spark中将UniForm表作为Iceberg表读取

您可以通过以下步骤在Apache Spark中将UniForm表作为Iceberg表读取:

  • 启动带有Iceberg的Apache Spark,并连接到UniForm所使用的Hive Metastore。关于如何运行带有Apache Spark的Iceberg并连接到Hive Metastore,请参考Iceberg文档

  • 使用SHOW TABLES命令查看目录中可用的Iceberg表列表。

  • 使用标准SQL(如SELECT)读取Iceberg表。

使用元数据JSON路径将UniForm表读取为Iceberg表

某些Iceberg客户端允许您通过提供版本化元数据文件的路径来注册外部Iceberg表。每当UniForm将Delta表的新版本转换为Iceberg时,它都会创建一个新的元数据JSON文件。

使用元数据JSON路径配置Iceberg的客户端包括BigQuery。有关配置详情,请参阅Iceberg读取器客户端的文档。

Delta Lake 将 Iceberg 元数据存储在表目录下,采用以下模式:

<table-path>/metadata/v<version-number>-uuid.metadata.json

在Apache Spark中将UniForm表读取为Hudi表

您可以通过以下步骤将UniForm表作为Hudi表在Apache Spark中读取:

  • 查看Hudi文档了解如何在Apache Spark上运行Hudi

spark.read.format("hudi").option("hoodie.metadata.enable", "true").load("PATH_TO_UNIFORM_TABLE_DIRECTORY")

Delta与Iceberg/Hudi表版本

Delta Lake、Iceberg和Hudi都支持使用表版本或存储在表元数据中的时间戳进行时间旅行查询。

Delta和Iceberg表的版本既不会通过提交时间戳对齐,也不会通过版本ID对齐。然而,Delta和Hudi的提交时间戳是对齐的,但版本ID并不对齐。如果您想验证Iceberg/Hudi表的某个特定版本对应的是Delta表的哪个版本,可以使用Iceberg/Hudi表上设置的相应表属性。参见检查Iceberg/Hudi元数据生成状态

限制

警告

从Iceberg和Hudi的角度来看,UniForm是只读的。然而,这无法强制执行,因为对于Iceberg,UniForm使用HMS作为Iceberg目录;对于Hudi,元数据存储在文件系统上。如果有任何外部写入器(非Delta Lake)向这个Iceberg/Hudi表写入数据,可能会破坏您的Delta表并导致数据丢失,因为Iceberg/Hudi写入器可能会执行Delta不知情的数据清理或垃圾回收操作。

存在以下限制:

  • UniForm不适用于启用了删除向量的表。请参阅什么是删除向量?

  • 启用了UniForm的Delta表不支持VOID类型。

  • Iceberg/Hudi 客户端只能从 UniForm 读取数据,不支持写入操作。

  • 无论是否使用UniForm,Iceberg/Hudi读取器客户端可能存在各自的限制。请参阅您目标客户端的文档。

启用UniForm后,以下Delta Lake功能适用于Delta客户端,但Iceberg不支持这些功能:

  • 变更数据订阅

  • Delta 共享