Apache Iceberg™ 表的存储

Snowflake 表通常使用 Snowflake 管理的存储。相比之下,Snowflake 中的 Apache Iceberg™ 表使用由您配置和维护的外部存储。

本主题提供 Iceberg 表存储的概念信息和最佳实践。

外部卷

外部卷是一个命名的账户级 Snowflake 对象,用于将 Snowflake 连接到 Iceberg 表的外部云存储。外部卷存储您的存储位置的身份和访问管理 (IAM) 实体。Snowflake 使用 IAM 实体安全地连接到存储,以访问表数据、Iceberg 元数据以及存储表架构、分区和其他元数据的清单文件。

单个外部卷可以支持一个或多个 Iceberg 表。

每个外部卷都与特定 活动存储位置 相关联,单个外部卷可以支持多个 Iceberg 表。但是,所需的外部卷数量取决于您要如何存储、组织和保护表数据。

如果您想将 Snowflake-Iceberg 表的 所有 数据和元数据放在同一存储位置下的子目录中(例如,在同一 S3 桶中),则可以使用单个外部卷。要为 Snowflake 管理的表配置这些目录,请参阅 数据和元数据目录

或者,您可以创建多个外部卷以不同的方式保护不同的存储位置。例如,您可以创建以下外部卷:

  • 外部管理的 Iceberg 表的只读外部卷。

  • 配置为具有 Snowflake 管理的表具有读写权限的外部卷。

授予 Snowflake 对存储的访问权限

云提供商存储

要授予 Snowflake 对 Iceberg 表云存储位置的访问权限,请使用云提供商的 Identity and Access Management 服务。您授予身份或主体对您存储的有限访问权限,而无需交换密钥。这与 Snowflake 用于其他集成(包括存储集成)的访问模式相同。

创建 外部卷 时,Snowflake 会为您的整个 Snowflake 账户提供主体。主体如下所示,具体取决于您的云提供商:

云提供商

Snowflake 提供的主体

Amazon Web Services (AWS)

IAM 用户 (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-users)

Google Cloud

服务账户 (https://cloud.google.com/iam/docs/overview#service_account)

Azure

服务主体 (https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object)

Snowflake 直接与您的存储提供商进行身份验证,Snowflake 提供的主体将承担您指定的角色。该角色必须拥有在存储位置上执行操作的权限。例如,只有当角色拥有从存储位置读取的权限时,Snowflake 才能从该存储位置读取数据。

Snowflake 需要权限才能对 Iceberg 表执行以下操作:

Snowflake 管理的表

使用外部 Iceberg 目录的表

Amazon S3

  • s3:GetBucketLocation

  • s3:GetObject

  • s3:ListBucket

  • s3:PutObject

  • s3:DeleteObject

  • s3:GetObjectVersion

  • s3:DeleteObjectVersion

  • s3:GetBucketLocation

  • s3:GetObject

  • s3:ListBucket

  • s3:GetObjectVersion

Google Cloud Storage

  • storage.objects.create

  • storage.objects.delete

  • storage.objects.get

  • storage.objects.list

  • storage.buckets.get

  • storage.objects.get

  • storage.objects.list

Azure Storage

存储 Blob 数据贡献者角色 (https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/storage#storage-blob-data-contributor) 的所有允许操作

存储 Blob 数据阅读者角色 (https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/storage#storage-blob-data-reader) 的所有允许操作

备注

s3:PutObject 权限授予对外部卷位置的写入访问权限。要完全配置写入访问权限,您必须将外部卷的 ALLOW_WRITES 参数设置为 :code:`TRUE`(默认值)。

有关授予 Snowflake 对 Iceberg 表存储的访问权限的完整说明,请参阅以下主题:

兼容 S3 的存储

要授予 Snowflake 对 Iceberg 表的 兼容 S3 的存储位置 的访问权限,您需要在创建外部卷时指定一个 兼容 S3 的存储端点 并提供凭据。

仅外部管理的表支持兼容 S3 的存储。

有关说明,请参阅 为 S3 兼容存储配置外部卷

活动存储位置

每个外部卷都支持一个活动存储位置。如果在 CREATE EXTERNAL VOLUME 语句中指定了多个存储位置,Snowflake 将指定一个位置作为活动位置。在外部卷的生命周期内,活动位置将保持不变。

首次在 CREATE ICEBERG TABLE 语句中使用外部卷时,系统就会进行分配。Snowflake 使用以下逻辑选择活动位置:

  • 如果 STORAGE_LOCATIONS 列表包含一个或多个 本地 存储位置,Snowflake 将使用列表中的第一个本地存储位置。本地存储位置与您的 Snowflake 账户位于同一云提供商和同一区域。

  • 如果 STORAGE_LOCATIONS 列表不包含任何本地存储位置,Snowflake 将选择列表中的第一个位置。

备注

  • 仅当您使用外部 Iceberg 目录时,才支持跨云/跨区域 Iceberg 表。有关详细信息,请参阅 跨云/跨区域支持

  • 在 Snowflake 版本 7.44 之前创建的外部卷可能使用不同的逻辑来选择活动位置。

验证存储访问

要检查 Snowflake 是否能成功对您的存储提供商进行身份验证,请调用 SYSTEM$VERIFY_EXTERNAL_VOLUME 函数。

SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('my_s3_external_volume');
Copy

对于 Snowflake 管理的表,Snowflake 会在以下情况下自动验证对外部卷上 活动存储位置 的访问权限:

  • 首次在 Snowflake 管理的表的 CREATE ICEBERG TABLE 语句中指定该外部卷。

  • 首次将表转换为使用 Snowflake 作为 Iceberg 目录。

外部卷的 ALLOW_WRITES 属性必须设置为 TRUE

Snowflake 会尝试以下存储操作来验证存储位置。

  1. 编写测试文件。

  2. 读取文件。

  3. 列出文件路径的内容。

  4. 删除文件。

如果任何一项操作失败,则 CREATE ICEBERG TABLE(或 ALTER ICEBERG TABLE … CONVERT TO MANAGED)语句会失败并收到错误消息。

文件管理

本部分将根据 Iceberg 表的类型说明如何管理存储中的 Iceberg 表文件。

Snowflake 管理的表

重要

  • 不允许其他工具访问删除或覆盖与 Snowflake 管理的 Iceberg 表相关联的对象。

  • 确保 Snowflake 主体能访问表存储。有关更多信息,请参阅 授予 Snowflake 对存储的访问权限

虽然 可以配置和管理 Iceberg 表的存储位置,但 Snowflake 只对存储中属于 Snowflake 管理的表的对象(数据和元数据文件)进行操作。Snowflake 会定期对这些表对象进行维护,以优化查询性能并清理已删除的数据。

如果其他工具删除或覆盖 Snowflake 管理的表对象,查询可能会失败。同样,如果您撤销 Snowflake 主体对存储的访问权限,对表的查询和 Snowflake 的表维护操作也会失败。

当 Snowflake 删除 Snowflake 管理的表数据或删除表时,Snowflake 会在表保留期到期后删除对象。

数据和元数据目录

对于 Snowflake 管理的表,Snowflake 会将 Parquet 数据文件和表元数据写入外部云存储中的以下路径:

  • STORAGE_BASE_URL/BASE_LOCATION/data/

  • STORAGE_BASE_URL/BASE_LOCATION/metadata/

其中:

  • STORAGE_BASE_URL 是与外部卷关联的活动存储位置的基本 URL。

  • BASE_LOCATION 是外部卷相对路径下的目录名称(在 CREATE ICEBERG TABLE 语句中指定)。

** 为 BASE_LOCATION 指定一个空字符串**

如果为 BASE_LOCATION 指定一个空字符串 (''),Snowflake 会在 STORAGE_BASE_URL 下创建 data/metadata/ 目录。

例如:STORAGE_BASE_URL/data/

为多个表使用同一位置

如果您使用相同的存储位置并为多个表指定相同的基本位置,Snowflake 会将 所有 表的数据写入相同的 data/ 目录。同样,Snowflake 会将所有表的元数据写入同一个 metadata/ 目录。

** 使用 BASE_LOCATION 整理表存储**

要在同一 STORAGE_BASE_URL 下为多个 Iceberg 表整理存储中的文件,可考虑在 CREATE ICEBERG TABLE 语句中使用表名作为 BASE_LOCATION。这样,Snowflake 就会将数据和元数据写入与目录同名的目录。

例如:

CREATE OR REPLACE ICEBERG TABLE iceberg_table_1 (
  col_1 int,
  col_2 string
)
  CATALOG = 'SNOWFLAKE'
  EXTERNAL_VOLUME = 'iceberg_external_volume'
  BASE_LOCATION = 'iceberg_table_1';

CREATE OR REPLACE ICEBERG TABLE iceberg_table_2 (
  col_1 int,
  col_2 string
)
  CATALOG = 'SNOWFLAKE'
  EXTERNAL_VOLUME = 'iceberg_external_volume'
  BASE_LOCATION = 'iceberg_table_2';
Copy

该语句会在外部云存储中产生以下目录结构:

STORAGE_BASE_URL
|-- iceberg_table_1
|   |-- data/
|   |-- metadata/
|-- iceberg_table_2
|   |-- data/
|   |-- metadata/
Copy

使用外部目录的表

对于外部管理的 Iceberg 表或 ALLOW_WRITES 属性设置为 FALSE 的外部卷,Snowflake 不会写入或删除存储对象。

要访问表数据和元数据,Snowflake 会承担您为外部卷配置的访问控制角色。您授予角色访问存储位置(在桶或容器中)的权限。所有表数据和元数据文件都必须放在该位置。例如,如果您的存储位置是 S3 桶,那么您的所有数据和元数据文件都必须存在于该桶中的某个位置。

此外,转换表 不会重写任何数据或元数据文件。只有在您将表转换为使用 Snowflake 作为目录后,Snowflake 才会写入 Iceberg 表。

启用存储访问日志

要诊断问题并审核对外部卷相关存储位置的访问,可以启用存储日志记录。存储日志可帮助您确定文件丢失或损坏的原因。

启用存储提供商的日志记录。由于您拥有并管理 Iceberg 表的存储,Snowflake 无法在您的 Iceberg 存储位置启用日志或审核。

要了解存储提供商的存储访问日志,请参阅以下外部主题:

  • Amazon S3 的日志记录选项 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/logging-with-S3.html)

  • Google Cloud Storage 的使用日志和存储日志 (https://cloud.google.com/storage/docs/access-logs)

  • Azure 存储分析日志记录 (https://learn.microsoft.com/en-us/azure/storage/common/storage-analytics-logging)

利用版本控制和对象保留功能保护文件

如果您的 Iceberg 表数据位于中央数据存储库(或数据湖)中,并由多个工具和服务操作,则可能会发生意外删除或损坏。要保护 Iceberg 表数据并确保意外删除或覆盖数据的检索,请使用存储提供商提供的存储生命周期管理和版本控制。

通过生命周期管理,您可以为存储对象设置保留和跟踪规则。要了解存储提供商的生命周期管理,请参阅以下外部主题:

  • 管理 Amazon S3 的存储生命周期 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)

  • Google Cloud Storage 的对象生命周期管理 (https://cloud.google.com/storage/docs/lifecycle)

  • Azure 中的生命周期管理策略 (https://learn.microsoft.com/en-us/azure/storage/blobs/lifecycle-management-overview)

为支持对象恢复,您还可以启用外部云存储的版本控制。

  • 要为 Amazon S3 启用版本控制,请参阅 在桶上启用版本控制 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/manage-versioning-examples.html)。

  • 要为 Google Cloud Storage 启用版本控制,请参阅 使用对象版本控制 (https://cloud.google.com/storage/docs/using-object-versioning)。

  • 要为 Azure 启用版本控制,请参阅 启用 Blob 版本控制 (https://learn.microsoft.com/en-us/azure/storage/blobs/versioning-enable?tabs=portal#enable-blob-versioning)。

加密表文件

Snowflake 可以读取您使用常见的服务器端加密 (SSE) 方案加密的存储中的 Iceberg 表文件。您应该使用云服务提供商管理加密密钥,如果使用客户管理的密钥,则应授予 Snowflake 主体访问密钥的权限。

对于 Amazon S3,Snowflake 支持以下 SSE 选项:

SSE 选项

配置

使用 Amazon S3 托管密钥 (SSE-S3) 的 SSE

CREATE EXTERNAL VOLUME 命令中指定 ENCRYPTION = ( TYPE = 'AWS_SSE_S3' )

使用 AWS KMS 密钥 (SSE-KMS) 的 SSE

CREATE EXTERNAL VOLUME 命令中指定 ENCRYPTION = ( TYPE = 'AWS_SSE_KMS' KMS_KEY_ID='my_key' )

您还必须授予 SSE-KMS 加密所需的权限。有关说明,请参阅 为 Amazon S3 配置外部卷 中的第 3 步。

对于 Google Cloud Storage,Snowflake 支持以下 SSE 选项:

SSE 选项

配置

使用存储在 Google Cloud KMS 中的密钥的 SSE

CREATE EXTERNAL VOLUME 命令中指定 ENCRYPTION = ( TYPE = 'GCS_SSE_KMS' KMS_KEY_ID = 'my_key' )

您还必须 授予 GCS 服务账户对 Google Cloud Key Management Service 密钥的权限

语言: 中文