为 Iceberg 表配置存储

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

本主题提供概念信息和最佳实践,帮助您配置 Iceberg 表的 外部卷 并管理存储。

配置外部卷

您可以创建和配置 外部卷,以便与一个或多个 Iceberg 表进行搭配使用。必须先创建外部卷,然后才能创建 Iceberg 表。

有关具体说明,请参阅以下主题:

授予 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 Platform (GCP)

服务账户 (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 参数设置为 TRUE (默认值)。

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

分配活动存储位置

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

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

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

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

备注

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

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

验证存储访问

对于 Snowflake 管理的表,Snowflake 会验证对外部卷上 活动存储位置 的访问权限。外部卷的 ALLOW_WRITES 属性必须设置为 TRUE

在以下情况下会发生验证:

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

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

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 会定期生成元数据,并将元数据写入外部卷上的文件。

Snowflake 会使用 DATA_RETENTION_TIME_IN_DAYS 参数的值来确定以下内容:

  • 何时使旧表快照过期,以减少表元数据的大小。

  • 保留表元数据以支持 Time Travel 和取消删除表的时间。保留期到期时,Snowflake 会从外部卷位置删除为该表写入的任何表元数据和快照。

    警告

    Snowflake 不支持 Snowflake 管理的 Iceberg 表的 故障安全,因为表数据位于您管理的外部云存储中。要保护 Iceberg 表数据,您需要通过云提供商配置数据保护和恢复。

使用外部目录的表

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

元数据和保留

对于使用外部目录的表,Snowflake 会使用 DATA_RETENTION_TIME_IN_DAYS 参数的值来设置 Snowflake Time Travel 和取消删除表的保留期。当保留期到期时,Snowflake 不会 从外部云存储中删除表的 Iceberg 元数据或快照。

Snowflake 在表级别将 DATA_RETENTION_TIME_IN_DAYS 设置为以下值中的较小值:

  • 当前元数据文件中的 history.expire.max-snapshot-age-ms 值。Snowflake 会将值转换为天数(四舍五入)。

  • 以下值取决于您的 Snowflake 账户版本

    • Standard Edition:1 天。

    • Enterprise Edition(或更高版本):5 天。

您无法手动更改 Snowflake 中的 DATA_RETENTION_TIME_IN_DAYS 值。要更改值,必须更新元数据文件中的 history.expire.max-snapshot-age-ms,然后刷新表。

配置 Time Travel

借助 Time Travel,您可以查询表的数据保留期内的历史数据。当 Snowflake 删除 Snowflake 管理的表数据或删除表时,Snowflake 会在表保留期到期后删除对象。这可能会导致您的云存储提供商产生比数据表生命周期更长的费用。

您可以使用 DATA_RETENTION_TIME_IN_DAYS 对象参数为 Iceberg 表配置 Time Travel。

Snowflake 会使用 DATA_RETENTION_TIME_IN_DAYS 参数以不同方式处理元数据,这具体取决于 Iceberg 表的类型。有关更多信息,请参阅 管理存储中的文件

备注

任何类型的 Iceberg 表都不支持使用 history.expire.min-snapshots-to-keep 表属性 (https://iceberg.apache.org/docs/1.2.1/configuration/#table-behavior-properties) 指定默认的最小快照数。

启用存储访问日志

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

启用存储提供商的日志记录。由于您拥有并管理 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)。

加密 Iceberg 表文件

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 密钥的权限

在账户、数据库或架构级别设置外部卷

要定义用于 Iceberg 表的现有外部卷,您可以在以下几个级别上设置 EXTERNAL_VOLUME

账户:

账户管理员可以使用 ALTER ACCOUNT 命令设置账户的参数。如果为账户设置了该值,则默认情况下在账户中创建的所有 Iceberg 表都会读取和写入此外部卷。

对象:

用户可以执行适当的 CREATE <object>ALTER <object> 命令,以在数据库或架构级别上替换 EXTERNAL_VOLUME 参数值。系统会使用适用范围级别最低的声明:架构 > 数据库 > 账户。

除使用适当的 ALTER <object_type> 命令修改对象所需的最小权限之外,角色还必须拥有外部卷上的 USAGE 权限。

备注

对 EXTERNAL_VOLUME 参数的更改仅适用于更改 之后 创建的表。现有表将继续使用创建时指定的外部卷。

示例

以下语句为名为 my_database_1 的数据库设置外部卷 (my_s3_vol):

ALTER DATABASE my_database_1
  SET EXTERNAL_VOLUME = 'my_s3_vol';
Copy

在数据库级别设置外部卷后,可以在该数据库中创建 Iceberg 表,而无需指定外部卷。以下语句会在 my_database_1 中创建 Iceberg 表,该表使用 Snowflake 作为目录,并使用为数据库设置的默认外部卷 (my_s3_vol)。

CREATE ICEBERG TABLE iceberg_reviews_table (
  id STRING,
  product_name STRING,
  product_id STRING,
  reviewer_name STRING,
  review_date DATE,
  review STRING
)
CATALOG = 'SNOWFLAKE'
BASE_LOCATION = 'my/product_reviews/';
Copy
语言: 中文