Iceberg 与 Delta 表兼容性的通用格式 (UniForm)

Delta 通用格式 (UniForm) 允许使用 Iceberg 阅读器客户端读取 Delta 表。 此功能需要 Databricks Runtime 14.3 LTS 或更高版本。

重要

有关旧版 UniForm IcebergCompatV1 表功能的文档,请参阅旧版 UniForm IcebergCompatV1

UniForm 利用了 Delta Lake 和 Iceberg 都由 Parquet 数据文件和元数据层组成的事实。 UniForm 自动异步生成 Iceberg 元数据,而无需重写数据,因此 Iceberg 客户端可以像读取 Iceberg 表一样读取 Delta 表。 数据文件的单一副本可用于这两种格式。

可以配置外部连接,使 Unity Catalog 充当 Iceberg 目录。 请参阅使用 Unity Catalog Iceberg 目录端点读取

UniForm 使用 zstd 而非 snappy 作为基础 Parquet 数据文件的压缩编解码器。

注意

UniForm 元数据生成在用于将数据写入 Delta 表的计算上异步运行,这可能会加剧驱动程序资源使用状况。

要求

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

注意

无法对启用了 UniForm 的表启用删除向量。 对启用了删除向量的现有表启用 UniForm 时,UniForm 根据需要禁用和清除删除向量并重写数据文件。

启用 Delta UniForm

重要

启用 Delta UniForm 将设置 Delta 表功能 IcebergCompatV2,它是写入协议功能。 只有支持此表功能的客户端才能写入启用了 UniForm 的表。 必须使用 Databricks Runtime 14.3 LTS 或更高版本才能在启用此功能的情况下写入 Delta 表。

可以通过取消设置 delta.universalFormat.enabledFormats 表属性来关闭 UniForm。 启用列映射后将无法关闭它,并且无法撤消对 Delta Lake 读取器协议版本的升级。

必须设置以下表属性,以启用对 Iceberg 的 UniForm 支持:

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

还必须启用列映射才能使用 UniForm。 如果在创建表期间启用 UniForm,则这会自动启用,如以下示例所示:

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

可以使用以下语法对现有表启用 UniForm:

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

注意

此语法还可用于从使用表功能 IcebergCompatV1 的 UniForm 公共预览版升级。

此语法自动禁用和清除表中的删除向量。 根据需要重写现有文件,使其与 Iceberg 兼容。

首次启用 UniForm 时,异步元数据生成就开始了。 在外部客户端可以使用 Iceberg 查询表之前,必须完成此任务。 请参阅检查 Iceberg 元数据生成状态

注意

如果计划使用 BigQuery 作为 Iceberg 读取器客户端,则必须在 Azure Databricks 上将 spark.databricks.delta.write.dataFilesToSubdir 设置为 true,以满足 BigQuery 对数据布局的要求。

请参阅限制

UniForm 何时生成 Iceberg 元数据?

在 Delta Lake 写入事务完成后(使用完成 Delta 事务的相同计算),Azure Databricks 异步触发 Iceberg 元数据生成。 还可以手动触发 Iceberg 元数据生成。 请参阅手动触发 Iceberg 元数据转换

为了避免与 Iceberg 元数据生成相关的写入延迟,频繁提交的 Delta 表可能会将多个 Delta 提交捆绑到单一 Iceberg 提交中。

Delta Lake 确保在任何时候都只有一个 Iceberg 元数据生成进程在进行中。 触发第二个并发 Iceberg 元数据生成进程的提交将成功提交到 Delta,但其不会触发异步 Iceberg 元数据生成。 这可以防止频繁提交的工作负载的元数据生成的级联延迟(提交之间的秒到分钟)。

请参阅 Delta 和 Iceberg 表版本

检查 Iceberg 元数据生成状态

UniForm 将以下字段添加到 Unity Catalog 和 Iceberg 表元数据中,以跟踪元数据生成状态:

元数据字段 说明
converted_delta_version 已成功为其生成 Iceberg 元数据的最新版本 Delta 表。
converted_delta_timestamp 为其成功生成 Iceberg 元数据的最新 Delta 提交时间戳。

在 Azure Databricks 上,可通过执行一种操作来查看这些元数据字段:

  • 查看 DESCRIBE EXTENDED table_name 返回的 Delta Uniform Iceberg 部分。
  • 使用目录资源管理器查看表元数据。
  • 使用 REST API 获取表

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

SHOW TBLPROPERTIES <table-name>;

手动触发 Iceberg 元数据转换

可以手动触发最新版本 Delta 表的 Iceberg 元数据生成。 此操作同步运行,表示当它完成时,Iceberg 中可用的表内容反映了转换过程开始时可用的最新版本 Delta 表。

在正常情况下不需要进行此操作,但如果遇到以下情况,则会有所帮助:

  • 群集在自动生成元数据成功之前终止。
  • 错误或作业失败中断了元数据生成。
  • 不支持 UniForm Iceberg 元数据生成的客户端写入 Delta 表。

使用以下语法手动触发 Iceberg 元数据生成:

MSCK REPAIR TABLE <table-name> SYNC METADATA

请参阅 REPAIR TABLE

使用元数据 JSON 路径读取

一些 Iceberg 客户端要求提供版本控制元数据文件的路径,以注册外部 Iceberg 表。 每次 UniForm 将新版本 Delta 表转换为 Iceberg 时,它都会创建新的元数据 JSON 文件。

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

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

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

在 Azure Databricks 上,可通过执行一种操作来查看此元数据位置:

  • 查看 DESCRIBE EXTENDED table_name 返回的 Delta Uniform Iceberg 部分。
  • 使用目录资源管理器查看表元数据。
  • 将以下命令与 REST API 配合使用:
GET api/2.1/unity-catalog/tables/<catalog-name>.<schame-name>.<table-name>

响应包含以下信息:

{
    ...
          "delta_uniform_iceberg": {
              "metadata_location":  "<cloud-storage-uri>/metadata/v<version-number>-<uuid>.metadata.json"
    }
}

重要

基于路径的 Iceberg 读取器客户端可能需要手动更新和刷新元数据 JSON 路径来读取当前表版本。 用户在使用过期版本查询 Iceberg 表时可能会遇到错误,因为 Parquet 数据文件已使用 VACUUM 从 Delta 表中移除。

使用 Unity Catalog Iceberg 目录终结点读取

一些 Iceberg 客户端可以连接到 Iceberg REST 目录。 Unity Catalog 为 Delta 表(使用终结点 /api/2.1/unity-catalog/iceberg 启用了 UniForm)提供了 Iceberg REST 目录 API 的只读实现。 有关使用此 REST API 的详细信息,请参阅 Iceberg REST API 规范

已知支持 Iceberg 目录 API 的客户端包括 Apache Spark、Flink 和 Trino。 必须配置对包含已启用 UniForm 的 Delta 表的基础云对象存储的访问权限。 有关配置详细信息,请参阅 Iceberg 读取器客户端文档。

必须生成并配置 Azure Databricks 个人访问令牌,以允许其他服务连接到 Unity Catalog。 请参阅 Azure Databricks 自动化身份验证 - 概述

以下是配置 OSS Apache Spark 将 UniForm 读取为 Iceberg 的设置示例:

"spark.sql.extensions": "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions",
"spark.sql.catalog.unity"="org.apache.iceberg.spark.SparkCatalog",
"spark.sql.catalog.unity.catalog-impl": "org.apache.iceberg.rest.RESTCatalog",
"spark.sql.catalog.unity.uri": "<api-root>/api/2.1/unity-catalog/iceberg",
"spark.sql.catalog.unity.token":"<your_personal_access_token>",
"spark.sql.catalog.unity.io-impl": "org.apache.iceberg.aws.s3.S3FileIO

将已生成个人访问令牌的工作区的完整 URL 替换为 <api-root>

注意

使用此方法查询 Unity Catalog 中的表时,对象标识符使用以下模式:

unity.<catalog-name>.<schema-name>.<table-name>

此模式使用了 Unity Catalog 中相同的三层名称空间,但添加了额外的前缀 unity

Delta 和 Iceberg 版本

Delta Lake 和 Iceberg 都允许使用存储在表元数据中的表版本或时间戳进行按时间顺序查看查询。

通常,Iceberg 和 Delta 表的版本不按照提交时间戳或版本 ID 对齐。 如果希望验证指定版本的 Iceberg 表对应的 Delta 表版本,则可以使用在 Iceberg 表上设置的相应表格属性。 请参阅检查 Iceberg 元数据生成状态

限制

存在以下限制:

  • UniForm 不适用于已启用删除向量的表。 请参阅什么是删除向量?
  • 已启用 UniForm 的 Dealta 表不支持 VOID 类型。
  • Iceberg 客户端只能从 UniForm 读取。 不支持写入。
  • 不管 UniForm 如何,Iceberg 读取器客户端可能都有各自局限性。 请参阅所选客户端文档。
  • 即使启用了 UniForm,Delta Sharing 的收件人也仅可将表读取为 Delta。

启用 UniForm 时,更改数据馈送适用于 Delta 客户端,但在 Iceberg 中没有支持。

某些 Delta Sharing 读取器客户端不支持 UniForm 使用的一些 Delta Lake 表功能。 请参阅使用 Delta Sharing 安全共享数据和 AI 资产