自动刷新 Google Cloud Storage 的外部表¶
本主题说明如何使用 Google Cloud Storage (GCS) 事件的 Google Cloud Pub/Sub (https://cloud.google.com/storage/docs/reporting-changes) 消息触发外部表元数据的刷新。
备注
要完成本主题中描述的步骤,您必须使用对架构具有 CREATE STAGE 和 CREATE EXTERNAL TABLE 权限的角色。
此外,您必须具有对 Google Cloud Platform (GCP) 的管理员权限。如果您不是 GCP 管理员,请让您的 GCP 的管理员完成 先决条件 步骤。
请注意,只有 OBJECT_DELETE
和 OBJECT_FINALIZE
事件才会触发外部表元数据的刷新。Snowflake 建议您仅发送外部表支持的事件,以降低成本、事件干扰和延迟。
本主题内容:
云平台支持¶
托管在 Google Cloud Platform (GCP) 上的 Snowflake 账户支持使用 GCS Pub/Sub 事件消息触发外部元数据的自动刷新。
配置对 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
数据加载和卸载
:code:`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 权限。
以下示例会在活动架构中为用户会话创建一个名为 mystage
的暂存区。云存储 URL 包括路径 files
。该暂存区引用名为 my_storage_int
的存储集成。
USE SCHEMA mydb.public; CREATE STAGE mystage URL='gcs://load/files/' STORAGE_INTEGRATION = my_storage_int;
第 4 步:创建外部表¶
使用 CREATE EXTERNAL TABLE 命令创建外部表。
例如,在 mydb.public
架构中创建一个外部表,该表从 mystage
暂存区(具有 path1/
路径)中暂存的文件读取 JSON 数据。
INTEGRATION 参数引用您在 第 1 步:在 Snowflake 中创建通知集成 中创建的 my_notification_int
通知集成。集成名称必须全部大写。
请注意,AUTO_REFRESH
参数默认为 TRUE
:
CREATE OR REPLACE EXTERNAL TABLE ext_table
INTEGRATION = 'MY_NOTIFICATION_INT'
WITH LOCATION = @mystage/path1/
FILE_FORMAT = (TYPE = JSON);
具有自动刷新功能的外部暂存区现已配置完毕!
将新的或已更新的数据文件添加到 GCS 桶时,事件通知会通知 Snowflake 将它们扫描到外部表元数据中。
第 5 步:手动刷新外部表元数据¶
使用带有 REFRESH 参数的 ALTER EXTERNAL TABLE 手动刷新一次外部表元数据,例如:
ALTER EXTERNAL TABLE ext_table REFRESH; +---------------------------------------------+----------------+-------------------------------+ | file | status | description | |---------------------------------------------+----------------+-------------------------------| | files/path1/file1.json | REGISTERED_NEW | File registered successfully. | | files/path1/file2.json | REGISTERED_NEW | File registered successfully. | | files/path1/file3.json | REGISTERED_NEW | File registered successfully. | +---------------------------------------------+----------------+-------------------------------+
此步骤将元数据与暂存区中的文件列表和外部表定义中的路径进行同步。此外,此步骤确保外部表可以读取指定暂存区和路径中的数据文件,并且外部表定义中没有缺失任何文件。
如果 file
列中的文件列表不符合您的期望,请验证外部表定义和外部暂存区定义中的路径。外部表定义中的任何路径都会追加到暂存区定义中指定的任何路径。有关更多信息,请参阅 CREATE EXTERNAL TABLE。
重要
如果在创建外部表后,此步骤未成功完成至少一次,则在 Pub/Sub 通知首次自动刷新外部表元数据之前,查询外部表将不会返回任何结果。
此步骤确保元数据与自第 4 步以来发生的文件列表的任何变更同步。此后,Pub/Sub 通知会自动触发元数据刷新。
第 6 步:配置安全性¶
对于将用于查询外部表的每个附加角色,请使用 GRANT <privileges> 授予对各种对象(即数据库、架构、暂存区和表)的足够的访问控制权限:
对象 |
权限 |
备注 |
---|---|---|
数据库 |
USAGE |
|
架构 |
USAGE |
|
命名暂存区 |
USAGE、READ |
|
命名文件格式 |
USAGE |
可选;仅当 第 3 步:创建暂存区(如果需要) 中创建的暂存区引用命名文件格式时才需要。 |
外部表 |
SELECT |