将 Iceberg 表与 OneLake 配合使用

在 Microsoft OneLake 中,可以创建 Apache Iceberg 表的快捷方式,使其能够在各种 Fabric 工作负荷中使用。 此功能可以通过名为“元数据虚拟化”的功能实现,“元数据虚拟化”功能允许从快捷方式的角度将 Iceberg 表解释为 Delta Lake 表。 创建 Iceberg 表文件夹的快捷方式时,OneLake 会自动为该表生成相应的 Delta Lake 元数据(Delta 日志),从而可以通过快捷方式访问 Delta Lake 元数据。

重要

此功能目前为预览版

说明 Delta Lake 元数据虚拟化的关系图。

虽然本文提供将 Iceberg 表从 Snowflake 写入 OneLake 的指导,但此功能旨在与任何包含 Parquet 数据文件的 Iceberg 表一起使用。

创建 Iceberg 表的表快捷方式

如果在 OneLake 快捷方式支持的存储位置中已有 Iceberg 表,请按照以下步骤创建快捷方式并让 Iceberg 表以 Delta Lake 格式显示。

  1. 找到 Iceberg 表。 查找 Iceberg 表的存储位置,该表可以存储在 Azure Data Lake Storage、OneLake、Amazon S3、Google Cloud Storage 或 S3 兼容的存储服务中。

    注意

    如果你使用的是 Snowflake 并且不确定 Iceberg 表的存储位置,则可以运行以下语句以查看 Iceberg 表的存储位置。

    SELECT SYSTEM$GET_ICEBERG_TABLE_INFORMATION('<table_name>');

    运行此语句将返回 Iceberg 表的元数据文件的路径。 此路径指示哪个存储帐户包含 Iceberg 表。 例如,以下是查找存储在 Azure Data Lake Storage 中的 Iceberg 表的路径的相关信息:

    {"metadataLocation":"azure://<storage_account_path>/<path_within_storage>/<table_name>/metadata/00001-389700a2-977f-47a2-9f5f-7fd80a0d41b2.metadata.json","status":"success"}

    Iceberg 表文件夹需要包含一个 metadata 文件夹,其中至少包含一个以 .metadata.json 结尾的文件。

  2. 在 Fabric Lakehouse 中,在未启用架构的 Lakehouse 的“表”区域中创建一个新的快捷方式

    注意

    如果在 Lakehouse 的“表”文件夹下看到类似 dbo 的架构,则表示该 Lakehouse 已启用架构,但尚不兼容此功能。

    显示“表”下的快捷创建菜单项的屏幕截图。

  3. 对于快捷方式的目标路径,请选择 Iceberg 表文件夹。 Iceberg 表文件夹包含 metadatadata 文件夹。

  4. 创建快捷方式后,应会自动看到此表反映为 Lakehouse 中的 Delta Lake 表,可供在整个 Fabric 中使用。

    显示成功创建 Iceberg 表快捷方式的屏幕截图。

    如果新的 Iceberg 表快捷方式未显示为可用表,请查看故障排除部分。

使用 Snowflake 将 Iceberg 表写入 OneLake

如果在 Azure 上使用 Snowflake,可以按照以下步骤将 Iceberg 表写入 OneLake:

  1. 确保 Fabric 容量与 Snowflake 实例位于同一 Azure 位置。

    找到与 Fabric Lakehouse 关联的 Fabric 容量的位置。 打开包含 Lakehouse 的 Fabric 工作区的设置。

    显示 Fabric 容量区域的屏幕截图。

    在 Azure 帐户界面上的 Snowflake 左下角,检查 Snowflake 帐户的 Azure 区域。

    显示 Snowflake 帐户区域的屏幕截图。

    如果这些区域不同,则需要在与 Snowflake 帐户相同的区域使用不同的 Fabric 容量。

  2. 打开 Lakehouse 的“文件”区域的菜单,选择“属性”,然后复制该文件夹的 URL(HTTPS 路径)。

    显示“属性”菜单项的屏幕截图。

  3. 找到 Fabric 租户 ID。 选择 Fabric 用户界面右上角的用户配置文件,然后将鼠标悬停在“租户名称”旁边的信息气泡上。 复制租户 ID。

    显示租户 ID 的屏幕截图。

  4. 在 Snowflake 中,使用 Lakehouse 中“文件”文件夹的路径设置 EXTERNAL VOLUME可在此处找到有关设置 Snowflake 外部卷的详细信息。

    注意

    Snowflake 要求 URL 方案为 azure://,因此请务必将 https:// 更改为 azure://

    CREATE OR REPLACE EXTERNAL VOLUME onelake_exvol
    STORAGE_LOCATIONS =
    (
        (
            NAME = 'onelake_exvol'
            STORAGE_PROVIDER = 'AZURE'
            STORAGE_BASE_URL = 'azure://<path_to_Files>/icebergtables'
            AZURE_TENANT_ID = '<Tenant_ID>'
        )
    );
    

    在此示例中,使用此外部卷创建的任何表都存储在 Fabric Lakehouse 的 Files/icebergtables 文件夹中。

  5. 创建外部卷后,运行以下命令以检索 Snowflake 用于写入 OneLake 的应用程序的同意 URL 和名称。 Snowflake 帐户中的任何其他外部卷均可使用此应用程序。

    DESC EXTERNAL VOLUME onelake_exvol;
    

    此命令的输出返回 AZURE_CONSENT_URLAZURE_MULTI_TENANT_APP_NAME 属性。 记下这两个值。 Azure 多租户应用名称类似于 <name>_<number>,但只需捕获 <name> 部分。

  6. 在新浏览器选项卡中打开上一步的同意 URL。如果想要继续,请在提示时同意所需的应用程序权限。

  7. 返回 Fabric,打开工作区并选择“管理访问权限”,然后选择“添加人员或组”。 向 Snowflake 外部卷使用的应用程序授予将数据写入工作区中的 Lakehouse 所需的权限。 我们建议授予“参与者”角色

  8. 返回 Snowflake,使用新的外部卷创建 Iceberg 表。

    CREATE OR REPLACE ICEBERG TABLE MYDATABASE.PUBLIC.Inventory (
        InventoryId int,
        ItemName STRING
    )
    EXTERNAL_VOLUME = 'onelake_exvol'
    CATALOG = 'SNOWFLAKE'
    BASE_LOCATION = 'Inventory/';
    

    使用此语句,将在外部卷中定义的文件夹路径内创建一个名为 Inventory 的新 Iceberg 表文件夹。

  9. 向 Iceberg 表添加一些数据。

    INSERT INTO MYDATABASE.PUBLIC.Inventory
    VALUES
    (123456,'Amatriciana');
    
  10. 最后,在同一个 Lakehouse 的“表格”区域,可以为 Iceberg 表创建一个 OneLake 快捷方式。 通过该快捷方式,Iceberg 表将显示为 Delta Lake 表,以供 Fabric 工作负荷使用。

故障排除

以下提示可帮助确保 Iceberg 表与此功能兼容:

检查 Iceberg 表的文件夹结构

在首选的存储资源管理器工具中打开 Iceberg 文件夹,并查看 Iceberg 文件夹在其原始位置的目录列表。 应看到类似于以下示例的文件夹结构。

../
|-- MyIcebergTable123/
    |-- data/
        |-- snow_A5WYPKGO_2o_APgwTeNOAxg_0_1_002.parquet
        |-- snow_A5WYPKGO_2o_AAIBON_h9Rc_0_1_003.parquet
    |-- metadata/
        |-- 00000-1bdf7d4c-dc90-488e-9dd9-2e44de30a465.metadata.json
        |-- 00001-08bf3227-b5d2-40e2-a8c7-2934ea97e6da.metadata.json
        |-- 00002-0f6303de-382e-4ebc-b9ed-6195bd0fb0e7.metadata.json
        |-- 1730313479898000000-Kws8nlgCX2QxoDHYHm4uMQ.avro
        |-- 1730313479898000000-OdsKRrRogW_PVK9njHIqAA.avro
        |-- snap-1730313479898000000-9029d7a2-b3cc-46af-96c1-ac92356e93e9.avro
        |-- snap-1730313479898000000-913546ba-bb04-4c8e-81be-342b0cbc5b50.avro

如果未看到元数据文件夹,或者未看到本示例中显示的具有扩展名的文件,则可能没有正确生成的 Iceberg 表。

检查转换日志

将 Iceberg 表虚拟化为 Delta Lake 表时,可以在快捷方式文件夹内找到一个名为 _delta_log/ 的文件夹。 此文件夹包含转换成功后的 Delta Lake 格式的元数据(Delta 日志)。

此文件夹还包含 latest_conversion_log.txt 文件,其中包含最新尝试转换的成功或失败详细信息。

若要在创建快捷方式后查看此文件的内容,请在 Lakehouse 的“表格”区域下打开 Iceberg 表快捷方式菜单,然后选择“查看文件”

“查看文件”菜单项的屏幕截图。

应看到类似于以下示例的结构:

Tables/
|-- MyIcebergTable123/
    |-- data/
        |-- <data files>
    |-- metadata/
        |-- <metadata files>
    |-- _delta_log/   <-- Virtual folder. This folder doesn't exist in the original location.
        |-- 00000000000000000000.json
        |-- latest_conversion_log.txt   <-- Conversion log with latest success/failure details.

打开转换日志文件以查看最新的转换时间或失败详细信息。 如果未看到转换日志文件,则表示未尝试转换

如果未尝试转换

如果未看到转换日志文件,则表示未尝试转换。 以下是未尝试转换的两个常见原因:

  • 快捷方式未在正确的位置创建。

    为了将 Iceberg 表的快捷方式转换为 Delta Lake 格式,必须将快捷方式直接放在未启用架构的 Lakehouse 的“表”文件夹下。 如果希望表自动虚拟化为 Delta Lake 表,则不应将快捷方式放在“文件”部分或另一个文件夹下。

    显示“表”文件夹中快捷方式的正确位置的屏幕截图。

  • 快捷方式的目标路径不是 Iceberg 文件夹路径。

    创建快捷方式时,在目标存储位置中选择的文件夹路径必须是 Iceberg 表文件夹。 此文件夹包含 metadatadata 文件夹

    显示快捷方式创建过程中快捷目标路径的内容的屏幕截图。

限制和注意事项

使用此功能时,请记住以下临时限制:

  • 支持的数据类型

    以下 Iceberg 列数据类型使用此功能映射到其相应的 Delta Lake 类型。

    Iceberg 列类型 Delta Lake 列类型 注释
    int integer
    long long 请参阅“类型宽度问题”
    float float
    double double 请参阅“类型宽度问题”
    decimal(P, S) decimal(P, S) 请参阅“类型宽度问题”
    boolean boolean
    date date
    timestamp timestamp_ntz timestamp Iceberg 数据类型不包含时区信息。 Fabric 工作负荷不完全支持 timestamp_ntz Delta Lake 类型。 建议将时间戳与包含的时区结合使用。
    timestamptz timestamp 在 Snowflake 中,若要使用此类型,请在 Iceberg 表创建过程中将 timestamp_ltz 指定为列类型。 可在此处找到有关 Snowflake 支持的 Iceberg 数据类型的详细信息
    string string
    binary binary
  • 类型宽度问题

    如果使用 Snowflake 编写 Iceberg 表,并且该表包含列类型 INT64doubleDecimal,精度 > = 10,则生成的虚拟 Delta Lake 表可能并非可供所有 Fabric 引擎使用。 可能会看到以下错误:

    Parquet column cannot be converted in file ... Column: [ColumnA], Expected: decimal(18,4), Found: INT32.
    

    我们正在设法解决此问题。

    解决方法:如果使用 Lakehouse 表预览用户界面并看到此问题,可以通过切换到 SQL 终结点视图(右上角,选择 Lakehouse 视图,切换到 SQL 终结点)并在此处预览表来解决此错误。 如果随后切换回 Lakehouse 视图,则表预览应正确显示。

    如果正在运行 Spark 笔记本或作业并遇到此问题,可以通过将 spark.sql.parquet.enableVectorizedReader Spark 配置设置为 false 来解决此错误。 以下是在 Spark 笔记本中运行的 PySpark 命令示例:

    spark.conf.set("spark.sql.parquet.enableVectorizedReader","false")
    
  • Iceberg 表元数据存储不可移植

    Iceberg 表的元数据文件使用绝对路径引用来相互引用。 如果将 Iceberg 表的文件夹内容复制或移动到其他位置而不重写 Iceberg 元数据文件,则 Iceberg 读取器(包括此 OneLake 功能)将无法读取该表。

    解决方法:

    如果需要将 Iceberg 表移动到其他位置来使用此功能,请使用最初编写 Iceberg 表的工具在所需位置编写新的 Iceberg 表。

  • Iceberg 表深度必须大于根级别深度

    存储中的 Iceberg 表文件夹必须位于比 Bucket 或容器级别更深的目录中。 直接存储在 Bucket 或容器根目录中的 Iceberg 表可能无法虚拟化为 Delta Lake 格式。

    我们正在努力改进以消除此要求。

    解决方法:

    确保任何 Iceberg 表都存储在比 Bucket 或容器的根目录更深的目录中。

  • Iceberg 表文件夹必须仅包含一组元数据文件

    如果在 Snowflake 中删除并重新创建 Iceberg 表,则不会清理元数据文件。 此行为是为了支持 Snowflake 中的 UNDROP 功能。 但是,由于快捷方式直接指向某个文件夹,并且该文件夹现在包含多个元数据文件集,因此在删除旧表的元数据文件之前,我们无法转换该表。

    目前,在这种情况下尝试转换会导致旧表内容和架构信息显示在虚拟化 Delta Lake 表中。

    我们正在努力修复以下问题:如果在 Iceberg 表的元数据文件夹中发现多组元数据文件,转换将失败。

    解决方法:

    为了确保转换后的表反映表的正确版本,请执行以下操作:

    • 确保不要在同一文件夹中存储多个 Iceberg 表。
    • 在重新创建表之前,在删除 Iceberg 表文件夹后清理其任何内容。
  • 元数据更改不会立即反映

    如果对 Iceberg 表进行元数据更改(例如添加列、删除列、重命名列或更改列类型),则在进行数据更改(例如添加一行数据)之前,可能无法重新转换该表。

    我们正在努力修复此问题,以便获取包含最新元数据更改的正确的最新元数据文件。

    解决方法:

    对 Iceberg 表进行架构更改后,添加一行数据或对数据进行任何其他更改。 完成更改后,应该能够刷新并查看 Fabric 中表的最新视图。

  • 尚不支持启用架构的工作区

    如果在启用架构的 Lakehouse 中创建 Iceberg 快捷方式,则不会针对该快捷方式进行转换。

    我们正在努力改进以消除此限制。

    解决方法:

    使用具有此功能的未启用架构的 Lakehouse。 可以在 Lakehouse 创建期间配置此设置。

  • 区域可用性限制

    此功能在以下区域中尚不可用:

    • 卡塔尔中部
    • 挪威西部

    解决方法:

    附加到其他区域中 Fabric 容量的工作区可以使用此功能。 查看可使用 Microsoft Fabric 的区域的完整列表。

  • 不支持专用链接

    已启用专用链接的租户或工作区当前不支持此功能。

    我们正在努力改进以消除此限制。

  • 表大小限制

    我们暂时限制此功能支持的 Iceberg 表的大小。 Parquet 数据文件的最大支持数量约为 5,000 个数据文件,或大约 10 亿行(以先到达的限制为准)。

    我们正在努力改进以消除此限制。

  • OneLake 快捷方式必须位于同一区域

    我们暂时限制了使用指向 OneLake 位置的快捷方式来使用此功能:快捷方式的目标位置必须与快捷方式本身位于同一区域。

    我们正在努力改进以消除此要求。

    解决方法:

    如果你有指向另一个 Lakehouse 中的 Iceberg 表的 OneLake 快捷方式,请确保另一个 Lakehouse 与同一区域的容量相关联。