自动刷新 Google Cloud Storage 的目录表¶
本主题提供有关使用 Google Cloud Pub/Sub (https://cloud.google.com/storage/docs/reporting-changes) 消息为 Google Cloud Storage (GCS) 事件触发目录表元数据刷新的说明。
备注
要完成本主题中描述的步骤,您必须使用对架构具有 CREATE STAGE 权限的角色。
此外,您必须具有对 Google Cloud Platform (GCP) 的管理员权限。如果您不是 GCP 管理员,请让您的 GCP 的管理员完成 先决条件 步骤。
请注意,只有 OBJECT_DELETE
和 OBJECT_FINALIZE
事件会触发目录表的刷新。Snowflake 建议您仅发送目录表支持的事件,以降低成本、事件干扰和延迟。
本主题内容:
云平台支持¶
托管在以下 云平台 上的 Snowflake 账户支持使用 GCS Pub/Sub 事件消息触发自动目录元数据刷新:
Amazon Web Services (AWS)
Google Cloud Platform
对于任一云托管平台上的账户,配置此支持的说明都是相同的。
配置对 Cloud Storage 的安全访问¶
备注
如果您已配置对存储数据文件的 GCS 桶的安全访问,则可以跳过此部分。
本部分介绍如何配置 Snowflake 存储集成对象,以将云存储的身份验证责任委托给 Snowflake Identity and Access Management (IAM) 实体。
本部分介绍如何使用存储集成来允许 Snowflake 从外部(即 Cloud Storage)暂存区中引用的 Google Cloud Storage 桶读取数据和写入数据。集成是命名的一类 Snowflake 对象,无需传递显式云提供商凭据,例如密钥或访问令牌;相反,集成对象会引用 Cloud Storage 服务账户。组织中的管理员会在 Cloud Storage 账户中授予服务账户权限。
管理员还可以将用户限制为使用集成的外部暂存区访问的一组特定的 Cloud Storage 桶(和可选路径)。
备注
要完成本部分中说明的操作,您需要以项目编辑者的身份访问您的 Cloud Storage 项目。如果您不是项目编辑者,请让您的 Cloud Storage 管理员执行这些任务。
确认 Snowflake 支持托管您的存储的 Google Cloud Storage 区域。有关更多信息,请参阅 支持的云区域。
下图显示了 Cloud Storage 暂存区的集成流程:
外部(即 Cloud Storage)暂存区在其定义中引用了存储集成对象。
Snowflake 会自动将存储集成与为您的账户创建的 Cloud Storage 服务账户相关联。Snowflake 创建一个服务账户,该账户由 Snowflake 账户中的所有 GCS 存储集成引用。
Cloud Storage 项目的项目编辑者会向服务账户授予访问暂存区定义中引用的桶的权限。请注意,许多外部暂存区对象可以引用不同的桶和路径,并使用相同的集成进行身份验证。
当用户从暂存区加载或卸载数据时,Snowflake 会在允许或拒绝访问之前验证授予桶服务账户的权限。
本部分内容:
第 1 步:在 Snowflake 中创建云存储集成¶
使用 CREATE STORAGE INTEGRATION 命令创建集成。集成是一个 Snowflake 对象,它将外部云存储的身份验证责任委托给 Snowflake 生成的实体(即 Cloud Storage 服务账户)。为了访问 Cloud Storage 桶,Snowflake 会创建一个服务账户,该账户有权访问存储您的数据文件的桶。
单个存储集成可以支持多个外部(即 GCS)暂存区。暂存区定义中的 URL 必须与为 STORAGE_ALLOWED_LOCATIONS 参数指定的 GCS 桶(和可选路径)一致。
备注
只有账户管理员(具有 ACCOUNTADMIN 角色的用户)或具有全局 CREATE INTEGRATION 权限的角色才能执行此 SQL 命令。
CREATE STORAGE INTEGRATION <integration_name>
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'GCS'
ENABLED = TRUE
STORAGE_ALLOWED_LOCATIONS = ('gcs://<bucket>/<path>/', 'gcs://<bucket>/<path>/')
[ STORAGE_BLOCKED_LOCATIONS = ('gcs://<bucket>/<path>/', 'gcs://<bucket>/<path>/') ]
其中:
integration_name
是新集成的名称。bucket
是用于存储数据文件(例如mybucket
)的 Cloud Storage 桶的名称。在创建或修改引用此集成的暂存区时,必需的 STORAGE_ALLOWED_LOCATIONS 参数和可选的 STORAGE_BLOCKED_LOCATIONS 参数分别限制或阻止对这些桶的访问。path
是一个可选路径,可用于提供对桶中对象的精细控制。
以下示例创建一个集成,该集成明确限制使用该集成引用两个桶和路径之一的外部暂存区。在后面的步骤中,我们将创建一个引用这些桶和路径之一的外部暂存区。
也使用此集成的其他外部暂存区可以引用允许的桶和路径:
CREATE STORAGE INTEGRATION gcs_int TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'GCS' ENABLED = TRUE STORAGE_ALLOWED_LOCATIONS = ('gcs://mybucket1/path1/', 'gcs://mybucket2/path2/') STORAGE_BLOCKED_LOCATIONS = ('gcs://mybucket1/path1/sensitivedata/', 'gcs://mybucket2/path2/sensitivedata/');
第 2 步:检索 Snowflake 账户的 Cloud Storage 服务账户¶
执行 DESCRIBE INTEGRATION 命令以检索为您的 Snowflake 账户自动创建的 Cloud Storage 服务账户的 ID:
DESC STORAGE INTEGRATION <integration_name>;
其中:
integration_name
是您在 第 1 步:在 Snowflake 中创建云存储集成 (本主题内容)中创建的集成的名称。
例如:
DESC STORAGE INTEGRATION gcs_int; +-----------------------------+---------------+-----------------------------------------------------------------------------+------------------+ | property | property_type | property_value | property_default | +-----------------------------+---------------+-----------------------------------------------------------------------------+------------------| | ENABLED | Boolean | true | false | | STORAGE_ALLOWED_LOCATIONS | List | gcs://mybucket1/path1/,gcs://mybucket2/path2/ | [] | | STORAGE_BLOCKED_LOCATIONS | List | gcs://mybucket1/path1/sensitivedata/,gcs://mybucket2/path2/sensitivedata/ | [] | | STORAGE_GCP_SERVICE_ACCOUNT | String | service-account-id@project1-123456.iam.gserviceaccount.com | | +-----------------------------+---------------+-----------------------------------------------------------------------------+------------------+
输出中的 STORAGE_GCP_SERVICE_ACCOUNT 属性显示为您的 Snowflake 账户创建的 Cloud Storage 服务账户(例如 service-account-id@project1-123456.iam.gserviceaccount.com
)。我们会为您的整个 Snowflake 账户预置一个 Cloud Storage 服务账户。所有 Cloud Storage 集成都使用该服务账户。
第 3 步:授予服务账户访问桶对象的权限¶
以下分步说明描述了如何在 Google Cloud Platform Console 中配置 Snowflake 的 IAM 访问权限,以便您可以使用 Cloud Storage 桶来加载和卸载数据:
创建自定义 IAM 角色¶
创建具有访问桶和获取对象所需权限的自定义角色。
以项目编辑者身份登录 Google Cloud Platform Console。
从主页仪表板中选择 IAM & Admin » Roles。
选择 Create Role。
为自定义角色输入 Title 和 Description (可选)。
选择 Add Permissions。
筛选权限列表,并从列表中添加以下内容:
操作
所需权限
仅加载数据
storage.buckets.get
storage.objects.get
storage.objects.list
使用清除选项加载数据,在暂存区上执行 REMOVE 命令
storage.buckets.get
storage.objects.delete
storage.objects.get
storage.objects.list
数据加载和卸载
storage.buckets.get
(用于计算数据传输成本)storage.objects.create
storage.objects.delete
storage.objects.get
storage.objects.list
仅数据卸载
storage.buckets.get
storage.objects.create
storage.objects.delete
storage.objects.list
选择 Add。
选择 Create。
将自定义角色分配给 Cloud Storage 服务账户¶
以项目编辑者身份登录 Google Cloud Platform Console。
从主页仪表板中选择 Cloud Storage » Buckets。
筛选桶列表,然后选择创建存储集成时指定的桶。
选择 Permissions » View by principals,然后选择 Grant access。
在 Add principals 下,粘贴 第 2 步:检索 Snowflake 账户的 GCS 服务账户 的输出中的服务账户名称。
在 Assign roles 下,选择先前创建的自定义 IAM 角色,然后选择 Save。
授予 Cloud Storage 服务账户对 Cloud Key Management Service 加密密钥的权限¶
备注
仅当 您的 GCS 桶使用存储在 Google Cloud Key Management Service (Cloud KMS) 中的密钥进行加密时,才需要执行此步骤。
以项目编辑者身份登录 Google Cloud Platform Console。
从主页仪表板中,搜索并选择 Security » Key Management。
选择分配给 GCS 桶的密钥环。
点击右上角的 SHOW INFO PANEL。密钥环的信息面板将滑出。
点击 ADD PRINCIPAL 按钮。
在 New principals 字段中,从 第 2 步:检索 Snowflake 账户的 Cloud Storage 服务账户 (本主题内容)的 DESCRIBE INTEGRATION 输出中搜索服务账户名称。
从 Select a role 下拉列表中,选择
Cloud KMS CrytoKey Encryptor/Decryptor
角色。点击 Save 按钮。服务账户名称将添加到信息面板中的 Cloud KMS CrytoKey Encryptor/Decryptor 角色下拉列表中。
使用 GCS Pub/Sub 配置自动化¶
先决条件¶
本主题中的说明假定已创建并配置了以下项:
- GCP 账户:
从 GCS 桶接收事件消息的 Pub/Sub 主题。有关更多信息,请参阅 创建 Pub/Sub 主题 (本主题内容)。
从 Pub/Sub 主题接收事件消息的订阅。有关更多信息,请参阅 创建 Pub/Sub 订阅 (本主题内容)。
有关信息,请参阅 Pub/Sub 文档 (https://cloud.google.com/pubsub/docs)。
- Snowflake:
将加载数据的 Snowflake 数据库中的目标表。
创建 Pub/Sub 主题¶
使用 Cloud Shell (https://cloud.google.com/shell) 或 Cloud SDK (https://cloud.google.com/sdk) 创建 Pub/Sub 主题。
执行以下命令创建主题,并使其能够监听指定 GCS 桶中的活动。
$ gsutil notification create -t <topic> -f json gs://<bucket-name> -e OBJECT_FINALIZE -e OBJECT_DELETE
其中:
<topic>
是主题的名称。<bucket-name>
是 GCS 桶的名称。
如果主题已存在,则该命令将使用该主题;如果不存在,将创建一个新主题。
有关更多信息,请参阅 Pub/Sub 文档中的 将 Pub/Sub 通知用于 Cloud Storage (https://cloud.google.com/storage/docs/reporting-changes)。
创建 Pub/Sub 订阅¶
使用 Cloud Console、gcloud
命令行工具或 Cloud Pub/Sub API,在 Pub/Sub 主题上创建一个采用拉取传递方式的订阅。有关信息,请参阅 Pub/Sub 文档中的 管理主题和订阅 (https://cloud.google.com/pubsub/docs/admin)。
备注
Snowflake 仅支持使用默认拉取传递的 Pub/Sub 订阅。不支持推送传递。
检索 Pub/Sub 订阅 ID¶
在这些指令中使用 Pub/Sub 主题订阅 ID 来允许 Snowflake 访问事件消息。
以项目编辑者身份登录 Google Cloud Platform Console。
从主页控制面板中选择 Big Data » Pub/Sub » Subscriptions。
复制主题订阅的 Subscription ID 列中的 ID
第 1 步:在 Snowflake 中创建通知集成¶
使用 CREATE NOTIFICATION INTEGRATION 命令创建通知集成。通知集成引用 Pub/Sub 订阅。Snowflake 将通知集成与为您的账户创建的 GCS 服务账户相关联。Snowflake 创建一个服务账户,该账户由 Snowflake 账户中的所有 GCS 通知集成引用。
备注
只有账户管理员(具有 ACCOUNTADMIN 角色的用户)或具有全局 CREATE INTEGRATION 权限的角色才能执行此 SQL 命令。
通知集成的 GCS 服务账户不同于为存储集成创建的服务账户。
一个通知集成支持一个 Google Cloud Pub/Sub 订阅。在多个通知集成中引用相同的 Pub/Sub 订阅可能会导致目标表中缺少数据,因为事件通知在通知集成之间是分开的。
CREATE NOTIFICATION INTEGRATION <integration_name>
TYPE = QUEUE
NOTIFICATION_PROVIDER = GCP_PUBSUB
ENABLED = true
GCP_PUBSUB_SUBSCRIPTION_NAME = '<subscription_id>';
其中:
integration_name
是新集成的名称。subscription_id
是您在 检索 Pub/Sub 订阅 ID 中记录的订阅名称。
例如:
CREATE NOTIFICATION INTEGRATION my_notification_int
TYPE = QUEUE
NOTIFICATION_PROVIDER = GCP_PUBSUB
ENABLED = true
GCP_PUBSUB_SUBSCRIPTION_NAME = 'projects/project-1234/subscriptions/sub2';
第 2 步:授予 Snowflake 对 Pub/Sub 订阅的访问权限¶
执行 DESCRIBE INTEGRATION 命令以检索 Snowflake 服务账户 ID:
DESC NOTIFICATION INTEGRATION <integration_name>;
其中:
integration_name
是您在 第 1 步:在 Snowflake 中创建通知集成 中创建的集成的名称。
例如:
DESC NOTIFICATION INTEGRATION my_notification_int;
在 GCP_PUBSUB_SERVICE_ACCOUNT 列中记录服务账户名称,格式如下:
<service_account>@<project_id>.iam.gserviceaccount.com
以项目编辑者身份登录 Google Cloud Platform Console。
从主页控制面板中选择 Big Data » Pub/Sub » Subscriptions。
选择要配置访问权限的订阅。
点击右上角的 SHOW INFO PANEL。订阅的信息面板将滑出。
点击 ADD PRINCIPAL 按钮。
在 New principals 字段中,搜索您记录的服务账户名称。
从 Select a role 下拉列表中,选择 Pub/Sub Subscriber。
点击 Save 按钮。服务账户名称将添加到信息面板中的 Pub/Sub Subscriber 角色下拉列表中。
导航到 Cloud Console 中的 Dashboard 页面,然后从下拉列表中选择您的项目。
点击 ADD PEOPLE TO THIS PROJECT 按钮。
添加您记录的服务账户名称。
从 Select a role 下拉列表中,选择 Monitoring Viewer。
点击 Save 按钮。服务账户名称将添加到 Monitoring Viewer 角色中。
第 3 步:创建包含目录表的暂存区¶
使用 CREATE STAGE 命令创建引用您的 GCS 桶的外部暂存区。Snowflake 将暂存数据文件读入目录表元数据。或者,您可以使用现有的外部暂存区。
备注
要配置对云存储位置的安全访问,请参阅 配置对 Cloud Storage 的安全访问 (本主题内容)。
要在 CREATE STAGE 语句中引用存储集成,角色必须具有对存储集成对象的 USAGE 权限。
-- External stage
CREATE [ OR REPLACE ] [ TEMPORARY ] STAGE [ IF NOT EXISTS ] <external_stage_name>
<cloud_storage_access_settings>
[ FILE_FORMAT = ( { FORMAT_NAME = '<file_format_name>' | TYPE = { CSV | JSON | AVRO | ORC | PARQUET | XML } [ formatTypeOptions ] } ) ]
[ directoryTable ]
[ COPY_OPTIONS = ( copyOptions ) ]
[ COMMENT = '<string_literal>' ]
其中:
directoryTable ::= [ DIRECTORY = ( ENABLE = { TRUE | FALSE } [ AUTO_REFRESH = { TRUE | FALSE } ] [ NOTIFICATION_INTEGRATION = '<notification_integration_name>' ] ) ]
目录表参数 (directoryTable
)¶
ENABLE = TRUE | FALSE
指定是否向暂存区添加目录表。当值为 TRUE 时,将创建包含暂存区的目录表。
默认:
FALSE
AUTO_REFRESH = TRUE | FALSE
指定当 新的或更新的 数据文件在 URL 值中指定的命名外部暂存区中可用时,Snowflake 是否应支持触发目录表元数据自动刷新。
TRUE
Snowflake 支持触发目录表元数据自动刷新。
FALSE
Snowflake 不支持触发目录表元数据自动刷新。必须使用 ALTER STAGE ... REFRESH 定期手动刷新目录表元数据,以使元数据与暂存区路径中的当前文件列表同步。
默认:
FALSE
NOTIFICATION_INTEGRATION = '<notification_integration_name>'
指定用于使用 Pub/Sub 通知自动刷新目录表元数据的通知集成的名称。通知集成是一个 Snowflake 对象,它在 Snowflake 和第三方云消息队列服务之间提供一个接口。
集成名称必须全部大写。
以下示例会在活动架构中为用户会话创建一个名为 mystage
的暂存区。云存储 URL 包括路径 files
。该暂存区引用名为 my_storage_int
的存储集成。
NOTIFICATION_INTEGRATION 参数引用您在 第 1 步:在 Snowflake 中创建通知集成 中创建的 my_notification_int
集成:
USE SCHEMA mydb.public;
CREATE STAGE mystage
URL='gcs://mybucket/files/'
STORAGE_INTEGRATION = my_storage_int
DIRECTORY = (
ENABLE = true
AUTO_REFRESH = true
NOTIFICATION_INTEGRATION = 'MY_NOTIFICATION_INT'
);
备注
URL 值中的存储位置必须以正斜杠 (
/
) 结尾。集成名称必须全部大写。
将新的或更新的数据文件添加到云存储位置时,事件通知会通知 Snowflake 将它们扫描到目录表元数据中。
第 4 步:手动刷新目录表元数据¶
使用 ALTER STAGE 命令手动刷新目录表中的元数据。
语法¶
ALTER STAGE [ IF EXISTS ] <name> REFRESH [ SUBPATH = '<relative-path>' ]
其中:
REFRESH
访问目录表定义中引用的暂存数据文件并更新表元数据:
路径中的新文件将添加到表元数据中。
对路径中文件的更改将在表元数据中更新。
路径中不再存在的文件将从表元数据中移除。
目前,每次将文件添加到暂存区、更新或删除文件时,都需要执行此命令。此步骤将元数据与目录表的暂存区定义中的最新关联文件集同步。
SUBPATH = '<relative-path>'
(可选)指定相对路径以刷新数据文件的特定子集的元数据。
示例¶
在名为 mystage
的暂存区中手动刷新目录表元数据:
ALTER STAGE mystage REFRESH;
重要
如果在创建目录表后至少一次未成功完成此步骤,则在通知事件触发目录表元数据首次自动刷新之前,查询目录表不会返回任何结果。
第 5 步:配置安全性¶
对于将用于查询目录表的每个附加角色,请使用 GRANT <privileges> 命令对各种对象(即数据库、架构和暂存区)授予足够的访问控制权限:
对象 |
权限 |
备注 |
---|---|---|
数据库 |
USAGE |
|
架构 |
USAGE |
|
命名暂存区 |
USAGE、READ |
|
命名文件格式 |
USAGE |
可选;仅当您创建的暂存区引用命名文件格式时才需要。 |