Apache Iceberg™ 表¶
Snowflake 的 Apache Iceberg™ 表将典型 Snowflake 表的性能和查询语义与您管理的外部云存储结合在一起。它们非常适合您无法存储在或选择不存储在 Snowflake 中的现有数据湖。
Iceberg 表使用 Apache Iceberg™ (https://iceberg.apache.org/) 开放表格式规范,该规范为以开放格式存储的数据文件提供了一个抽象层,并支持多种功能,例如:
ACID(原子性、一致性、隔离性、持久性)事务
架构演化
隐藏式分区
表快照
Snowflake 支持使用 Apache Parquet™ (https://parquet.apache.org/) 文件格式的 Iceberg 表。
开始使用¶
要开始使用 Iceberg 表,请参阅 教程:创建第一个 Apache Iceberg™ 表。
工作原理¶
本部分提供有关在 Snowflake 中使用 Iceberg 表的特定信息。要详细了解 Iceberg 表格式规范,请参阅官方的 Apache Iceberg 文档 (https://iceberg.apache.org/docs/latest/) 和 Iceberg 表规范 (https://iceberg.apache.org/spec/)。
数据存储¶
Iceberg 表将其数据和元数据文件存储在外部云存储位置(Amazon S3、Google Cloud Storage 或 Azure Storage)。外部存储不是 Snowflake 的一部分。您负责外部云存储位置的所有管理,包括数据保护和恢复的配置。Snowflake 不为 Iceberg 表提供 故障安全 存储。
Snowflake 使用 外部卷 连接到存储位置,Iceberg 表不会产生 Snowflake 存储成本。有关更多信息,请参阅 计费。
要了解有关 Iceberg 表存储的更多信息,请参阅 Apache Iceberg™ 表的存储。
外部卷¶
外部卷是一个命名的账户级 Snowflake 对象,用于将 Snowflake 连接到 Iceberg 表的外部云存储。外部卷存储您的存储位置的身份和访问管理 (IAM) 实体。Snowflake 使用 IAM 实体安全地连接到存储,以访问表数据、Iceberg 元数据以及存储表架构、分区和其他元数据的清单文件。
单个外部卷可以支持一个或多个 Iceberg 表。
要为 Iceberg 表设置外部卷,请参阅 配置外部卷。
目录¶
Iceberg 目录使计算引擎能够管理和加载 Iceberg 表。该目录构成了 Iceberg 表规范 (https://iceberg.apache.org/spec/#overview) 的第一个架构层,并且必须支持:
存储一个或多个 Iceberg 表的当前元数据指针。元数据指针将表名称映射到该表的当前元数据文件的位置。
执行原子操作,以便您可以更新表的当前元数据指针。
要了解有关 Iceberg 目录的更多信息,请参阅 Apache Iceberg 文档 (https://iceberg.apache.org/terms/#catalog-implementations)。
Snowflake 支持不同的 目录选项。例如,您可以使用 Snowflake 作为 Iceberg 目录,或者使用 目录集成 将 Snowflake 连接到外部 Iceberg 目录。
目录集成¶
目录集成是一个命名的、账户级别的 Snowflake 对象,用于存储有关您的表元数据在以下场景中如何组织的信息:
当您不使用 Snowflake 作为 Iceberg 目录 时。例如,如果您的表由 AWS Glue 管理,则需要目录集成。
当您想要与 Snowflake Open Catalog 集成时:
在 Snowflake Open Catalog 中使用 Snowflake 查询 Iceberg 表。
将 Snowflake 管理的 Iceberg 表与 Snowflake Open Catalog 集成,以便第三方计算引擎可以查询该表。
单个目录集成可以支持一个或多个使用相同外部目录的 Iceberg 表。
要设置目录集成,请参阅 配置目录集成。
元数据和快照¶
Iceberg 使用基于快照的查询模型,在该模型中,使用清单文件和元数据文件映射数据文件。快照表示表在某个时间点的状态,用于访问表中数据文件的完整集合。
要了解有关表元数据和 Time Travel 支持的信息,请参阅 Apache Iceberg™ 表的元数据与保留。
跨云/跨区域支持¶
Snowflake 支持使用与托管您的 Snowflake 账户的云提供商不同的云提供商(位于不同的区域)的外部卷存储位置。
表类型 |
跨云/跨区域支持 |
备注 |
---|---|---|
使用有 目录集成 的外部目录的表 |
✔ |
如果 Snowflake 账户和外部卷位于不同区域,则在您查询表时,外部云存储账户会产生出口费用。 |
使用 Snowflake 作为目录 的表 |
✔ |
如果 Snowflake 账户和外部卷位于不同区域,则在您查询表时,外部云存储账户会产生出口费用。 这些表会产生跨区域数据传输的使用费用。有关更多信息,请参阅 计费。 |
计费¶
当您使用 Iceberg 表时,Snowflake 会向您的账户收取虚拟仓库(计算)使用费和云服务费。如果您使用 自动刷新,Snowflake 还会向您的账户开具账单。
如果 Snowflake 管理的 Iceberg 表是跨云/跨区域的,则 Snowflake 会将您的跨区域数据传输费用按 DATA_LAKE 中的 TRANSFER_TYPE 类型计费。要了解更多信息,请参阅:
ORGANIZATION_USAGE 架构中的 DATA_TRANSFER_HISTORY 视图。
ACCOUNT_USAGE 架构中的 DATA_TRANSFER_HISTORY 视图。
Snowflake 不会 向您的账户收取以下费用:
Iceberg 表存储成本。云存储提供商会直接向您收取数据存储使用费。
Iceberg 表使用的活动字节。但是,INFORMATION_SCHEMA.TABLE_STORAGE_METRICS 和 ACCOUNT_USAGE.TABLE_STORAGE_METRICS 视图会显示 Iceberg 表的 ACTIVE_BYTES,以帮助您跟踪表占用的存储空间。要查看示例,请参阅 检索存储指标。
备注
如果 Snowflake 账户和外部卷位于不同区域,则在您查询表时,外部云存储账户会产生出口费用。
目录选项¶
Snowflake 支持以下 Iceberg 目录选项:
使用 Snowflake 作为 Iceberg 目录
使用外部 Iceberg 目录
下表总结了这两种目录选择之间的差异。
读取权限 |
✔ |
✔ |
写入权限 |
✔ |
✔ 对外部管理表的写入支持 处于预览版阶段。 |
跨区域写入权限 |
✔ |
✔ 与 对外部托管表的写入支持 |
数据和元数据存储 |
外部卷(云存储) |
外部卷(云存储) |
Snowflake 平台支持 |
✔ |
|
与 Snowflake Open Catalog 集成 |
✔ 您可以将 Snowflake 管理的表与 Open Catalog 同步,以使用其他计算引擎查询表。 |
✔ 您可以使用 Snowflake 来查询或写入由 Open Catalog 托管的 Iceberg 表。 |
✔ |
✔ |
使用 Snowflake 作为目录¶
使用 Snowflake 作为 Iceberg 目录(Snowflake 管理的 Iceberg 表)的 Iceberg 表提供完整的 Snowflake 平台支持,以及读写权限。表数据和元数据存储在 Snowflake 使用 外部卷 访问的外部云存储中。Snowflake 处理表的全部生命周期维护工作,例如压缩。
使用外部目录¶
使用外部目录的 Iceberg 表提供有限的 Snowflake 平台支持。
对于此表类型,Snowflake 使用 目录集成 来检索有关 Iceberg 元数据和架构的信息。
您可以使用该选项为以下来源创建 Iceberg 表:
远程 Iceberg REST 目录,包括 AWS Glue 和 Snowflake Open Catalog。Snowflake 支持对使用远程 Iceberg REST 目录的外部托管表进行写入。
Snowflake 不承担表的任何生命周期管理工作。
表数据和元数据存储在 Snowflake 使用 外部卷 访问的外部云存储中。
备注
如果您想为使用外部目录的 Iceberg 表提供全面的 Snowflake 平台支持,则可将其转换为使用 Snowflake 作为目录。有关更多信息,请参阅 转换 Apache Iceberg™ 表以使用 Snowflake 作为目录。
下图显示了 Iceberg 表如何使用与外部 Iceberg 目录的目录集成。
注意事项和限制¶
以下注意事项和限制适用于 Iceberg 表,并且可能会发生变更:
云和区域
Iceberg 表适用于所有 Snowflake 账户、所有云平台和所有区域。
支持跨云/跨区域的表。有关更多信息,请参阅 跨云/跨区域支持。
Iceberg
支持 Apache Iceberg 规范的版本 1 和 2,但以下 功能 (https://iceberg.apache.org/spec/) 除外:
利用
bucket
转换函数进行的 Iceberg 分区会影响使用条件子句筛选结果的查询的性能。对于不由 Snowflake 管理的 Iceberg 表,请注意以下几点:
只要在快照过期之前定期刷新表,就支持恢复到在创建表后生成的任何快照。
不支持转换带有非物化标识分区列的表。当表使用 Parquet 文件中不存在的源列定义身份转换时,将创建非物化身份分区列。
对于 行级删除:
Snowflake 仅支持 位置删除 (https://iceberg.apache.org/spec/#position-delete-files)。
为了在使用行级删除时获得最佳读取性能,请执行定期压缩和表维护以删除旧的删除文件。有关信息,请参阅 维护使用外部目录的表。
使用位置删除功能时,当前不支持自动刷新。
过多的位置删除(尤其是悬空位置删除)可能会阻碍表的创建和刷新操作。要避免此问题,请执行表维护以删除多余的位置删除。
使用的表维护方法取决于您的外部 Iceberg 引擎。例如,您可以使用带有
delete-file-threshold
或rewrite-all
选项的 Sparkrewrite_data_files
方法。有关更多信息,请参阅 Apache Iceberg™ 文档中的 rewrite_data_files (https://iceberg.apache.org/docs/latest/spark-procedures/#rewrite_data_files)。
文件格式
Iceberg 表支持 Apache Parquet 文件。
不支持使用无符号整型逻辑类型的 Parquet 文件。
对于使用
LIST
逻辑类型的 Parquet 文件,请注意以下几点:
支持带
element
关键字的三级注释结构。有关更多信息,请参阅 ` Parquet 逻辑类型定义 <https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#lists (https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#lists)>`_。如果您的 Parquet 文件使用带array
关键字的过时格式,您必须根据支持的格式重新生成数据。
外部卷
不得使用存储集成访问外部卷中的云存储位置。
必须为创建的每个外部卷配置单独的信任关系。
您可以使用 出站专用连接 访问由 Snowflake 管理的 Iceberg 表和使用目录集成进行对象存储的 Iceberg 表,但不能用于访问使用其他目录集成的 Iceberg 表。
创建 Snowflake 管理的表后,即使您重命名表,其在外部存储中文件的路径也 不会 更改。
Snowflake 不支持 S3 桶名称包含句点的外部卷(例如
my.s3.bucket
)。S3 不支持名称中带句点的虚拟托管样式桶的 SSL,而 Snowflake 使用虚拟托管样式路径和 HTTPS 来访问 S3 中的数据。
元数据文件
元数据文件无法识别 Iceberg 表的最新快照。
无法使用 ALTER ICEBERG TABLE 命令修改数据文件或快照的位置。要修改这些设置中的任一个,必须使用 CREATE OR REPLACE ICEBERG TABLE 语法重新创建表。
使用外部目录的表:
确保清单文件不包含重复内容。如果在 相同 的快照中存在重复文件,Snowflake 会返回一个包含重复文件路径的错误。
如果 Parquet 元数据包含无效的 UTF-8 字符,则无法创建表。确保 Parquet 元数据符合 UTF-8 标准。
Snowflake 可检测在 Snowflake 外生成的 Parquet 元数据中的损坏和不一致,并通过错误消息突显问题。
即使表元数据不一致,也可以创建、刷新或查询外部管理(或转换)的表。写入 Iceberg 表数据时,确保表元数据统计信息(如
RowCount
或NullCount
)与数据内容相匹配。对于使用 Snowflake 作为目录的表,Snowflake 会单独处理 DDL 语句,且生成元数据的方式可能与其他目录不同。有关更多信息,请参阅 DDL 语句。
群集
群集 支持取决于 Iceberg 表的类型。
表类型
备注
使用 Snowflake 作为 Iceberg 目录的表
使用 CREATE ICEBERG TABLE 或者 ALTER ICEBERG TABLE 命令设置群集密钥。要设置或管理群集密钥,请参阅 CREATE ICEBERG TABLE(使用 Snowflake 作为 Iceberg 目录) 和 ALTER ICEBERG TABLE。
使用外部目录的表
不支持群集。
转换的表
仅当转换表后创建了文件,或者之后使用 DML 语句修改了文件,Snowflake 才会群集文件。
Delta
Snowflake 支持 Delta 阅读器版本 2,可以读取引擎使用 Delta Lake 版本 2.2.0 编写的所有表格。
从带有分区列的 Delta 表文件创建的 Iceberg 表不支持 Snowflake 流。不过,从 无 分区列的 Delta 文件创建的表支持仅插入流。
动态表不支持从 2024_04 版本捆绑包之前创建的 Delta 文件中创建的 Iceberg 表。
Snowflake 不支持从 AWS Glue Data Catalog 中的 Delta 表定义创建 Iceberg 表。
不支持使用以下任何功能或数据类型的 Parquet 文件(Delta 表的数据文件):
字段 IDs。
INTERVAL 数据类型。
精度高于 38 的 DECIMAL 数据类型。
LIST 或 MAP 类型的一级或两级表示。
无符号整型 (INT(signed = false))。
FLOAT16 数据类型。
您可以为 TIMESTAMP 使用 Parquet 物理类型
int96
,但 Snowflake 不支持为 TIMESTAMP_NTZ 使用int96
。
有关 Delta 数据类型和 Iceberg 表的更多信息,请参阅 Delta 数据类型。
每次您使用 CREATE/ALTER ...REFRESH。如果您的表有超过 1000 个提交文件,您可以进行额外的手动刷新。每次刷新过程都从上一次停止的地方继续进行。
备注
Snowflake 在创建 Iceberg 表时使用 Delta 检查点文件。1,000 个提交文件限制只适用于最近一次检查点之后的提交。
刷新现有表时,Snowflake 会处理 Delta 提交文件,但不会处理检查点文件。如果表维护移除了源 Delta 表的陈旧日志和数据文件,则 Snowflake 中基于 Delta 的 Iceberg 表的刷新频率应高于 Delta 日志和数据文件的保留期。
目前不支持以下 Delta Lake 功能:行跟踪、删除矢量文件、更改数据文件、更改元数据、DataChange、CDC、协议演进。
自动刷新
对于在 Snowflake 8.22 版之前创建的目录集成(基于 Delta 表的目录集成对应版本为 9.2 之前),必须先手动设置
REFRESH_INTERVAL_SECONDS
参数,然后才能对依赖于该目录集成的表启用自动刷新。有关说明,请参阅 ALTER CATALOG INTEGRATION ... SET AUTO_REFRESH。对于 对象存储的目录集成,只有与
TABLE_FORMAT = DELTA
的集成才支持自动刷新。对于频繁更新的表,使用较短的轮询间隔 (
REFRESH_INTERVAL_SECONDS
) 可能会导致性能下降。
目录链接数据库和自动表发现
仅当您使用 Iceberg REST 的目录集成(例如 Snowflake Open Catalog)时才支持。
计费:在预览期间,Snowflake 不对目录链接的数据库计费。当 Apache Iceberg™ 目录链接的数据库正式发布时,开始计费。
要将自动表发现限制为一组特定的命名空间,请使用 ALLOWED_NAMESPACES 参数。您也可以使用 BLOCKED_NAMESPACES 参数来屏蔽一组命名空间。
Snowflake 不同步远程目录访问控制(用户或角色)。
您可以在目录链接的数据库中创建架构或外部管理的 Iceberg 表。目前不支持创建其他 Snowflake 对象。
延迟:
对于链接到远程目录中 7,500 个命名空间的数据库,发现命名空间和表大约需要一小时。
对于包含 500,000 个表的远程目录,自动刷新过程大约需要一小时才能完成。对于具有不同延迟要求的命名空间,我们建议您创建单独的目录链接的数据库。每个数据库都应引用具有相应自动刷新间隔 (REFRESH_INTERVAL_SECONDS) 的目录集成。
对于目录链接的数据库中的 Iceberg 表:
Snowflake 不复制远程目录表属性(例如保留策略或缓冲区),并且目前不支持更改表属性。
默认情况下,自动刷新 处于启用状态。如果外部表的
table-uuid
和目录链接的数据库表不匹配,则刷新失败,Snowflake 将该表从目录链接的数据库中删除;Snowflake 不会更改远程表。如果您从远程目录中删除表,Snowflake 会将该表从目录链接的数据库中删除。此操作是异步进行的,因此您可能不会立即在远程目录中看到更改。
如果您重命名远程目录中的表,Snowflake 会从目录链接的数据库中删除现有表,并使用新名称创建一个表。
支持掩码策略和标签。不支持其他特定于 Snowflake 的功能,包括复制、克隆和共享。
您为 NAMESPACE_FLATTEN_DELIMITER 参数选择的字符不会出现在远程命名空间中。在自动发现过程中,Snowflake 会跳过任何包含分隔符的命名空间,并且不会在您目录链接的数据库中创建相应的架构。
如果为 NAMESPACE_FLATTEN_DELIMITER 参数指定
_
、$
、大写字母或数字以外的任何值,则在查询表时必须将架构名称放在引号中。对于链接到 AWS Glue 的数据库,必须使用小写字母,并将架构、表和列名称用双引号引起来。对于其他仅支持小写标识符的 Iceberg REST 目录,这也是必需的。
以下示例显示了有效查询:
CREATE SCHEMA "s1";以下语句无效,因为它们使用大写字母或省略了双引号:
CREATE SCHEMA s1; CREATE SCHEMA "Schema1";不支持使用 UNDROP ICEBERG TABLE。
使用外部卷的表支持与列表共享。目前不支持直接共享。
写入目录链接的数据库中的表:
不支持已售凭据。
目前不支持写入嵌套命名空间中的表。
外部托管写入支持
Snowflake 为外部托管的表提供数据定义语言 (DDL) 和数据操作语言 (DML) 命令。但是,您可以使用外部目录和外部存储提供商提供的工具来配置元数据和数据保留。有关更多信息,请参阅 使用外部目录的表。
对于写入,Snowflake 确保在更新 Snowflake 中的表之前将更改提交到您的远程目录。
如果您使用目录链接的数据库,则可以使用带列定义的 CREATE ICEBERG TABLE 语法在 Snowflake 和 远程目录中创建表。如果您使用标准的 Snowflake 数据库(未链接到目录),则必须先在远程目录中创建表。之后,您可以使用 CREATE ICEBERG TABLE(Iceberg REST 目录) 语法在 Snowflake 中创建一个 Iceberg 表并将数据写入该表。
对于 AWS Glue Data Catalog:通过 Snowflake 删除外部托管的表不会删除基础表文件。此行为特定于 AWS Glue Data Catalog 的实现。
如果您曾参与此功能的非公开预览,则您账户中的定位行级删除功能可能已默认启用。要进行检查,请运行以下命令:
SHOW PARAMETERS LIKE 'ENABLE_ICEBERG_MERGE_ON_READ' IN ACCOUNT;如果该参数在您的账户中可见(无论其值如何),则会启用位置删除功能。要关闭位置删除,请在表、架构或数据库级别将
ENABLE_ICEBERG_MERGE_ON_READ
参数设置为 FALSE。不支持对包含以下 Iceberg 数据类型的外部托管表进行写入操作:
uuid
fixed(L)
在使用 Snowflake 写入外部托管的 Iceberg 表时,以下功能暂不支持:
目录分发的凭据。
GCS 或 Azure 外部卷的服务器端加密 (SSE)。
多语句事务Snowflake 仅支持自动提交事务。
转换为 Snowflake 托管的表。
不符合 Iceberg REST 协议的外部 Iceberg 目录。
行级删除(读取时合并)。
创建表时使用 OR REPLACE 选项。
如果使用 AWS Glue 作为远程目录,应使用 CREATE TABLE ... AS SELECT 语法。
要在目录链接数据库中创建架构,请注意以下事项:
仅当您使用目录链接的数据库时,CREATE SCHEMA 命令才会在远程目录中创建相应的命名空间。
不支持 ALTER 和 CLONE 选项。
架构名称不支持分隔符。仅支持字母数字架构名称。
You can set a target file size for a table's Parquet files. For more information, see 设置目标文件大小.
第三方客户端对 Iceberg 数据、元数据的访问
第三方客户端无法向使用 Snowflake 作为目录的 Iceberg 表追加、删除或者更新或插入数据。
不支持的功能
所有 Iceberg 表目前不支持以下 Snowflake 功能:
启用 Cross-Cloud Auto-Fulfillment 的列表。
复制 Iceberg 表、外部卷或目录集成。
Snowflake 加密
使用 :doc:/sql-reference/stored-procedures/associate_semantic_category_tags` 存储过程标记 </user-guide/object-tagging/introduction>`
外部托管的 Iceberg 表不支持以下功能: