自动刷新 Amazon S3 的目录表

本主题提供有关使用 Amazon SQS (Simple Queue Service) (https://aws.amazon.com/sqs/) 通知为 S3 桶自动创建目录表和刷新目录表元数据的说明。此操作会将元数据与外部暂存区和路径中的最新一组关联文件同步,即:

  • 路径中的新文件将添加到表元数据中。

  • 对路径中文件的更改将在表元数据中更新。

  • 路径中不再存在的文件将从表元数据中移除。

备注

  • 此功能仅适用于 AWS 上的 Snowflake 账户。

  • 要完成本主题中描述的任务,您必须使用对架构具有 CREATE STAGE 权限的角色。

    此外,您还必须具有 AWS 的管理权限。如果您不是 AWS 管理员,请让 AWS 管理员完成配置 AWS 事件通知的步骤。

  • Snowflake 建议您仅发送目录表支持的事件,以降低成本、事件干扰和延迟。

本主题内容:

使用 Amazon SQS 自动刷新目录表的限制

  • Virtual Private Snowflake (VPS)AWS PrivateLink 客户:目前 AWS 不支持将 Amazon SQS 用作 VPC 端点 (https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-endpoints.html)。虽然 VPC (包括 VPS)中的 AWS 服务可以与 SQS 通信,但此流量不在 VPC 内,因此不受 VPC 保护。

  • 当新文件到达受监控的 S3 桶并可以加载时,SQS 通知会通知 Snowflake。SQS 通知包含 S3 事件和文件名列表。它们 包括文件中的实际数据。

云平台支持

仅托管在 Amazon Web Services (AWS) 上的 Snowflake 账户支持使用 S3 事件消息触发外部元数据自动刷新。

配置对 Cloud Storage 的安全访问

备注

如果您已配置对存储数据文件的 S3 桶的安全访问,则可以跳过此部分。

本部分介绍如何配置 Snowflake 存储集成对象,以将云存储的身份验证责任委托给 Snowflake Identity and Access Management (IAM) 实体。

备注

我们强烈建议使用此选项,这样可以避免在访问云存储时提供 IAM 凭据。有关其他存储访问选项,请参阅 配置对 Amazon S3 的安全访问

本部分介绍如何使用存储集成来允许 Snowflake 从外部(如 S3)暂存区中引用的 Amazon S3 桶读取数据,并向其中写入数据。集成是已命名的第一类 Snowflake 对象,无需传递显式云提供商凭据(如密钥或访问令牌)。集成对象存储 AWS Identity and Access Management (IAM) 用户 ID。您组织中的管理员在 AWS 账户向集成授予 IAM 用户权限。

集成还可以列出桶(和可选路径),以限制用户在创建使用集成的外部暂存区时可以指定的位置。

备注

  • 需要在 AWS 中拥有创建和管理 IAM 策略和角色的权限,才能完成本部分中的说明。如果您不是 AWS 管理员,请让 AWS 管理员来执行这些任务。

  • 请注意,目前只能通过在同一政府区域的 AWS 上托管的 Snowflake 账户,使用存储集成访问 政府区域 中的 S3 存储。支持使用直接凭据从政府区域之外托管的账户访问 S3 存储。

下图显示了 S3 暂存区的集成流程:

Amazon S3 暂存区集成流程
  1. 外部(即 S3)暂存区在其定义中引用了存储集成对象。

  2. Snowflake 会自动将存储集成与为您的账户创建的 S3 IAM 用户相关联。Snowflake 会创建一个 IAM 用户,供 Snowflake 账户中的所有 S3 存储集成引用。

  3. 您组织中的 AWS 管理员向 IAM 用户授予权限,以访问暂存区定义中引用的桶。请注意,许多外部暂存区对象可以引用不同的桶和路径,并使用相同的存储集成进行身份验证。

当用户从暂存区加载或卸载数据时,Snowflake 会在允许或拒绝访问之前验证桶上授予 IAM 用户的权限。

本部分内容:

第 1 步:配置 S3 桶的访问权限

AWS 访问控制要求

Snowflake 需要对 S3 桶和文件夹拥有以下权限才能访问该文件夹(以及子文件夹)中的文件:

  • s3:GetBucketLocation

  • s3:GetObject

  • s3:GetObjectVersion

  • s3:ListBucket

作为最佳实践,Snowflake 建议创建一个供 Snowflake 访问 S3 桶的 IAM 策略。然后,您可以将策略附加到角色,并使用由 AWS 为角色生成的安全凭据来访问桶中的文件。

创建 IAM 策略

以下分步说明介绍如何在 AWS 管理控制台中配置 Snowflake 的访问权限以访问您的 S3 桶。

  1. 登录 AWS 管理控制台。

  2. 从主页仪表板搜索并选择 IAM

  3. 从左侧导航窗格中选择 Account settings

  4. Endpoints 列表中的 Security Token Service (STS) 下,找到账户所在的 Snowflake 区域。如果 STS status 不活动,请将切换按钮移至 Active

  5. 从左侧导航窗格中选择 Policies

  6. 选择 Create Policy

  7. 对于 Policy editor,选择 JSON

  8. 添加允许 Snowflake 访问 S3 桶和文件夹的策略文档。

    以下策略(采用 JSON 格式)为 Snowflake 提供使用单个桶和文件夹路径加载或卸载数据所需的权限。

    将文本复制并粘贴到策略编辑器中:

    备注

    • 确保用实际桶名称和文件夹路径前缀替换 bucketprefix

    • 政府区域 中的桶的 Amazon 资源名称 (ARN) 有一个 arn:aws-us-gov:s3::: 前缀。

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                  "s3:GetObject",
                  "s3:GetObjectVersion"
                ],
                "Resource": "arn:aws:s3:::<bucket>/<prefix>/*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:GetBucketLocation"
                ],
                "Resource": "arn:aws:s3:::<bucket>",
                "Condition": {
                    "StringLike": {
                        "s3:prefix": [
                            "<prefix>/*"
                        ]
                    }
                }
            }
        ]
    }
    
    Copy

    备注

    "s3:prefix": 条件设置为 ["*"] 或者 ["<path>/*"],以便分别向指定桶中的所有前缀或桶中的路径分别授予访问权限。

    注意 AWS 策略支持各种不同的安全用例。

  9. 选择 Next

  10. 输入 Policy name (例如 snowflake_access)和可选的 Description

  11. 选择 Create policy

第 2 步:在 AWS 中创建 IAM 角色

要在 AWS 管理控制台中为 Snowflake 配置访问权限,请执行以下操作:

  1. 在 Identity and Access Management (IAM) 控制面板的左侧导航窗格中,选择 Roles

  2. 选择 Create role

  3. 选择 AWS account 作为信任实体类型。

  4. Account ID 字段中,暂时输入自己的 AWS 账户 ID。在稍后的步骤中,您将修改信任关系并授予对 Snowflake 的访问权限。

  5. 选择 Require external ID 选项。外部 ID 用于向第三方(如 Snowflake)授予对 AWS 资源(例如 S3 桶)的访问权限。

    输入占位符 ID,例如 0000。在后续步骤中,您将修改 IAM 角色的信任关系并指定外部 ID 用于存储集成。

  6. 选择 Next

  7. 选择您在 第 1 步:配置 S3 桶访问权限 (本主题内容)中创建的策略。

  8. 选择 Next

    AWS 管理控制台中的 Review 页面
  9. 输入角色的名称和描述,然后选择 Create role

    您现在已经为一个桶创建了 IAM 策略,创建了一个 IAM 角色,并将策略附加到了该角色。

  10. 在角色摘要页面上,找到 Role ARN 值并将其记录下来。在下一步中,您将创建引用此角色的 Snowflake 集成。

备注

Snowflake 会将临时凭据缓存一段时间,但不能超过 60 分钟的过期时间。如果您撤消 Snowflake 的访问权限,用户或许也能够从云存储位置列出文件并访问数据,直到缓存过期。

第 3 步:在 Snowflake 中创建云存储集成

使用 CREATE STORAGE INTEGRATION 命令创建存储集成。存储集成是一个 Snowflake 对象,用于存储生成的身份和 S3 云存储访问管理 (IAM) 用户,以及一组可选的允许或阻止的存储位置(如桶)。组织中的云提供商管理员会将存储位置的权限授予生成的用户。此选项可让用户在创建暂存区或加载数据时无需提供凭据。

单个存储集成可以支持多个外部(如 S3)暂存区。暂存区定义中的 URL 必须与为 STORAGE_ALLOWED_LOCATIONS 参数指定的 S3 桶(和可选路径)一致。

备注

只有账户管理员(具有 ACCOUNTADMIN 角色的用户)或具有全局 CREATE INTEGRATION 权限的角色才能执行此 SQL 命令。

CREATE STORAGE INTEGRATION <integration_name>
  TYPE = EXTERNAL_STAGE
  STORAGE_PROVIDER = 'S3'
  ENABLED = TRUE
  STORAGE_AWS_ROLE_ARN = '<iam_role>'
  STORAGE_ALLOWED_LOCATIONS = ('s3://<bucket>/<path>/', 's3://<bucket>/<path>/')
  [ STORAGE_BLOCKED_LOCATIONS = ('s3://<bucket>/<path>/', 's3://<bucket>/<path>/') ]
Copy

其中:

  • integration_name 是新集成的名称。

  • iam_role 是您在 第 2 步:在 AWS 中创建 IAM 角色 (本主题内容)中创建的角色的 Amazon 资源名称 (ARN)。

  • bucket 是存储数据文件的 S3 桶的名称(例如 mybucket)。在创建或修改引用此集成的暂存区时,必需的 STORAGE_ALLOWED_LOCATIONS 参数和可选的 STORAGE_BLOCKED_LOCATIONS 参数分别限制或阻止对这些桶的访问。

  • path 是一个可选路径,可用于提供对桶中对象的精细控制。

下面的示例创建了一个集成,允许访问账户中的所有桶,但阻止访问定义的 sensitivedata 文件夹。

也使用此集成的其他外部暂存区可以引用允许的桶和路径:

CREATE STORAGE INTEGRATION s3_int
  TYPE = EXTERNAL_STAGE
  STORAGE_PROVIDER = 'S3'
  ENABLED = TRUE
  STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::001234567890:role/myrole'
  STORAGE_ALLOWED_LOCATIONS = ('*')
  STORAGE_BLOCKED_LOCATIONS = ('s3://mybucket1/mypath1/sensitivedata/', 's3://mybucket2/mypath2/sensitivedata/');
Copy

备注

(可选)使用 STORAGE_AWS_EXTERNAL_ID 参数来指定您自己的外部 ID。您可以选择此选项,在多个外部卷和/或存储集成中使用相同的外部 ID。

第 4 步:检索您的 Snowflake 账户的 AWSIAM 用户

  1. 要检索自动为您的 Snowflake 账户创建的 IAM 用户的 ARN,请使用 DESCRIBE INTEGRATION

    DESC INTEGRATION <integration_name>;
    
    Copy

    其中:

    例如:

    DESC INTEGRATION s3_int;
    
    +---------------------------+---------------+--------------------------------------------------------------------------------+------------------+
    | property                  | property_type | property_value                                                                 | property_default |
    +---------------------------+---------------+--------------------------------------------------------------------------------+------------------|
    | ENABLED                   | Boolean       | true                                                                           | false            |
    | STORAGE_ALLOWED_LOCATIONS | List          | s3://mybucket1/mypath1/,s3://mybucket2/mypath2/                                | []               |
    | STORAGE_BLOCKED_LOCATIONS | List          | s3://mybucket1/mypath1/sensitivedata/,s3://mybucket2/mypath2/sensitivedata/    | []               |
    | STORAGE_AWS_IAM_USER_ARN  | String        | arn:aws:iam::123456789001:user/abc1-b-self1234                                 |                  |
    | STORAGE_AWS_ROLE_ARN      | String        | arn:aws:iam::001234567890:role/myrole                                          |                  |
    | STORAGE_AWS_EXTERNAL_ID   | String        | MYACCOUNT_SFCRole=2_a123456/s0aBCDEfGHIJklmNoPq=                               |                  |
    +---------------------------+---------------+--------------------------------------------------------------------------------+------------------+
    
    Copy
  2. 记录以下属性的值:

    属性

    描述

    STORAGE_AWS_IAM_USER_ARN

    为您的 Snowflake 账户创建的 AWS IAM 用户,例如 arn:aws:iam::123456789001:user/abc1-b-self1234。Snowflake 会为整个 Snowflake 账户配置单一 IAM 用户。您账户中的所有 S3 存储集成都使用该 IAM 用户。

    STORAGE_AWS_EXTERNAL_ID

    Snowflake 与 AWS 建立信任关系所使用的外部 ID。如果创建存储集成时未指定外部 ID (STORAGE_AWS_EXTERNAL_ID),Snowflake 会生成一个 ID 供您使用。

    在下一部分中需要提供这些值。

第 5 步:授予访问桶对象的 IAM 用户权限

以下分步说明描述了如何在 AWS 管理控制台中配置 Snowflake 的 IAM 访问权限,以便您可以使用 S3 桶来加载和卸载数据:

  1. 登录 AWS 管理控制台。

  2. 选择 IAM

  3. 从左侧导航窗格中选择 Roles

  4. 选择在 第 2 步:在 AWS 中创建 IAM 角色 (本主题内容)中创建的角色。

  5. 选择 Trust relationships 选项卡。

  6. 选择 Edit trust policy

  7. 使用您在 第 4 步:检索 Snowflake 账户 AWS IAM 用户 (本主题内容)中记录的 DESC STORAGE INTEGRATION 输出值修改策略文档。

    IAM 角色的策略文档

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "AWS": "<snowflake_user_arn>"
          },
          "Action": "sts:AssumeRole",
          "Condition": {
            "StringEquals": {
              "sts:ExternalId": "<snowflake_external_id>"
            }
          }
        }
      ]
    }
    
    Copy

    其中:

    • snowflake_user_arn 是记录的 STORAGE_AWS_IAM_USER_ARN 值。

    • snowflake_external_id 是记录的 STORAGE_AWS_EXTERNAL_ID 值。

      在此示例中,snowflake_external_id 值为 MYACCOUNT_SFCRole=2_a123456/s0aBCDEfGHIJklmNoPq=

      备注

      出于安全原因,如果您在不指定外部 ID 的情况下创建新的存储集成(或使用 CREATE OR REPLACE STORAGE INTEGRATION 语法重新创建一个现有的存储集成),新的集成具有 不同 的外部 ID,所以它不能解析信任关系,除非更新信任策略。

  8. 选择 Update policy 保存更改。

备注

Snowflake 会将临时凭据缓存一段时间,但不能超过 60 分钟的过期时间。如果您撤消 Snowflake 的访问权限,用户或许也能够从云存储位置列出文件并加载数据,直到缓存过期。

确定正确的选项

在继续操作之前,请确定数据文件所在的 S3 桶中的目标路径(或 AWS 术语中的“前缀”)是否存在 S3 事件通知。AWS 规则禁止为同一路径创建冲突的通知。

支持以下使用 Amazon SQS 自动刷新目录表元数据的选项:

  • 选项 1.新建 S3 事件通知: 为 S3 桶中的目标路径创建事件通知。当路径中新建、删除或修改的文件需要刷新目录表元数据时,事件通知通过 SQS 队列通知 Snowflake。

    重要

    如果您的 S3 桶存在冲突事件通知,请改用选项 2。

  • 选项 2.现有事件通知: 将 Amazon Simple Notification Service (SNS) (https://aws.amazon.com/sns/) 配置为广播器,以便与多个端点(或“订阅者”,如 SQS 队列或 AWS Lambda 工作负载)共享给定路径的通知,包括用于目录表刷新自动化的 Snowflake SQS 队列。SNS 发布的 S3 事件通知通过 SQS 队列通知 Snowflake 路径中的文件更改。

选项 1:创建新的 S3 事件通知

本节介绍使用 S3 桶的 Amazon SQS (Simple Queue Service) (https://aws.amazon.com/sqs/) 通知自动刷新目录表元数据的最常用选项。这些步骤说明了如何为已存储数据文件的 S3 桶中的目标路径(或 AWS 术语中的“前缀”)创建事件通知。

重要

如果您的 S3 桶存在冲突事件通知,请使用 选项 2:配置 Amazon SNS (本主题内容)。AWS 规则禁止为同一目标路径创建冲突的通知。

第 1 步:创建包含目录表的暂存区

使用 CREATE STAGE 命令创建引用您的 S3 桶的外部暂存区。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>' ]
Copy

备注

URL 值中的存储位置必须以正斜杠 (/) 结尾。

其中:

directoryTable (for Amazon S3) ::=
  [ DIRECTORY = ( ENABLE = { TRUE | FALSE }
                  [ AUTO_REFRESH = { TRUE | FALSE } ] ) ]
Copy

目录表参数 (directoryTable)

ENABLE = TRUE | FALSE

指定是否向暂存区添加目录表。当值为 TRUE 时,将创建包含暂存区的目录表。

默认:FALSE

AUTO_REFRESH = TRUE | FALSE

指定当 新的或更新的 数据文件在 URL 值中指定的命名外部暂存区中可用时,Snowflake 是否应支持触发目录表元数据自动刷新。

TRUE

Snowflake 支持触发目录表元数据自动刷新。

FALSE

Snowflake 不支持触发目录表元数据自动刷新。必须使用 ALTER STAGE ... REFRESH 定期手动刷新目录表元数据,以使元数据与暂存区路径中的当前文件列表同步。

默认:FALSE

以下示例会在活动架构中为用户会话创建一个名为 mystage 的暂存区。云存储 URL 包括路径 files。该暂存区引用名为 my_storage_int 的存储集成。

USE SCHEMA mydb.public;
Copy
CREATE STAGE mystage
  URL='s3://load/files/'
  STORAGE_INTEGRATION = my_storage_int
  DIRECTORY = (
    ENABLE = true
    AUTO_REFRESH = true
  );
Copy

将新的或更新的数据文件添加到云存储位置时,事件通知会通知 Snowflake 将它们扫描到目录表元数据中。

第 2 步:配置事件通知

为您的 S3 桶配置事件通知,以便在新数据或更新数据可读取到目录表元数据时通知 Snowflake。自动刷新功能依赖于将事件通知从 S3 传递到 Snowflake 的 SQS 队列。

为便于使用,这些 SQS 队列由 Snowflake 创建和管理。DESCRIBE STAGE 命令输出显示 SQS 队列的 Amazon 资源名称 (ARN)。

  1. 执行 DESCRIBE STAGE 命令:

    DESC STAGE <stage_name>;
    
    Copy

    例如:

    DESC STAGE mystage;
    
    Copy

    注意 directory_notification_channel 字段中目录表 SQS 队列的 ARN。将 ARN 复制到方便的位置。

    备注

    根据 AWS 准则,Snowflake 为每个 S3 桶指定的 SQS 队列不超过一个。此 SQS 队列可由同一 AWS 账户中的多个桶共享。SQS 队列协调从同一 S3 桶读取数据文件的所有目录表的通知。当新的或修改的数据文件上传到桶时,所有与暂存区目录路径匹配的目录表定义都会将文件详细信息读入到其元数据中。

  2. 登录 AWS 管理控制台。

  3. 使用 Amazon S3 文档 (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-event-notifications.html) 中提供的说明为您的 S3 桶配置事件通知。填写如下字段:

    • Name:事件通知的名称(例如 Auto-ingest Snowflake)。

    • Events:选择 ObjectCreate (All)ObjectRemoved 选项。

    • Send to:从下拉列表中选择 SQS Queue

    • SQS:从下拉列表中选择 Add SQS queue ARN

    • SQS queue ARN:粘贴 DESC STAGE 输出中的 SQS 队列名称。

备注

这些说明旨在创建单一事件通知,来监控整个 S3 桶的活动。这是最简单的方法。此通知处理在 S3 桶目录中更精细级别配置的所有目录表。

或者,在上述步骤中,配置一个或多个路径和/或文件扩展名(或 AWS 术语中的 前缀后缀)来筛选事件活动。有关信息,请参阅相关 AWS 文档主题 (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) 的对象键名筛选信息。对您希望通知监控的每个其他路径或文件扩展名重复这些步骤。

请注意, AWS 将这些通知 队列配置 的数量限制为每个 S3 桶最多 100 个。

另请注意, AWS 不允许同一 S3 桶的重叠队列配置(跨事件通知)。例如,如果为 s3://mybucket/files/path1 配置现有通知,那么您就无法在更高级别创建另一个通知,例如 s3://mybucket/files,反之亦然。

具有自动刷新功能的外部暂存区现已配置完毕!

将新的或更新的数据文件添加到 S3 桶时,事件通知会通知 Snowflake 将它们扫描到目录表元数据中。

第 3 步:手动刷新目录表元数据

使用 ALTER STAGE 命令手动刷新目录表中的元数据。

ALTER STAGE [ IF EXISTS ] <name> REFRESH [ SUBPATH = '<relative-path>' ]
Copy

其中:

REFRESH

访问目录表定义中引用的暂存数据文件并更新表元数据:

  • 路径中的新文件将添加到表元数据中。

  • 对路径中文件的更改将在表元数据中更新。

  • 路径中不再存在的文件将从表元数据中移除。

目前,每次将文件添加到暂存区、更新或删除文件时,都需要执行此命令。此步骤将元数据与目录表的暂存区定义中的最新关联文件集同步。

SUBPATH = '<relative-path>'

(可选)指定相对路径以刷新数据文件的特定子集的元数据。

例如,在名为 mystage 的暂存区中手动刷新目录表元数据:

ALTER STAGE mystage REFRESH;
Copy

重要

如果在创建目录表后至少一次未成功完成此步骤,则在通知事件触发目录表元数据首次自动刷新之前,查询目录表不会返回任何结果。

第 4 步:配置安全性

对于将用于查询目录表的每个附加角色,请使用 GRANT <privileges> 授予对各种对象(即数据库、架构、暂存区和表)的足够的访问控制权限:

对象

权限

备注

数据库

USAGE

架构

USAGE

命名暂存区

USAGE、READ

命名文件格式

USAGE

选项 2:配置 Amazon SNS

本节介绍如何使用 S3 桶的 Amazon SQS (Simple Queue Service) (https://aws.amazon.com/sqs/) 通知自动触发目录表元数据刷新。这些步骤介绍了如何将 Amazon Simple Notification Service (SNS) (https://aws.amazon.com/sns/) 配置为广播器,以便将 S3 桶的事件通知发布到多个订阅者(例如 SQS 队列或 AWS Lambda 工作负载),包括用于目录表刷新自动化的 Snowflake SQS 队列。

备注

这些说明假设数据文件所在的 S3 桶中的目标路径存在事件通知。若不存在事件通知,则:

  • 改为按照 选项 1:创建新的 S3 事件通知 (本主题内容)操作。

  • 为您的 S3 桶创建事件通知,然后继续按照本主题中的说明操作。有关信息,请参阅 Amazon S3 文档 (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/enable-event-notifications.html)。

先决条件:创建 Amazon SNS 主题和订阅

  1. 在您的 SNS 账户中创建一个 AWS 主题来处理 S3 桶上 Snowflake 暂存区位置的所有消息。

  2. 将 S3 事件通知的目标目的地(如其他 SQS 队列或 AWS Lambda 工作负载)订阅到此主题。SNS 将您的桶的事件通知发布给该主题的所有订阅者。

有关信息,请参阅 SNS 文档 (https://aws.amazon.com/documentation/sns/)。

第 1 步:将 Snowflake SQS 队列订阅至 SNS 主题

  1. 登录 AWS 管理控制台。

  2. 从主页仪表板中选择 Simple Notification Service (SNS)。

  3. 从左侧导航窗格中选择 Topics

  4. 找到您的 S3 桶主题。注意主题 ARN。

  5. 使用 Snowflake 客户端,用您的 SNS 主题 ARN 查询 SYSTEM$GET_AWS_SNS_IAM_POLICY 系统函数:

    select system$get_aws_sns_iam_policy('<sns_topic_arn>');
    
    Copy

    该函数返回一个授予 Snowflake SQS 队列权限以订阅 SNS 主题的 IAM 策略。

    例如:

    select system$get_aws_sns_iam_policy('arn:aws:sns:us-west-2:001234567890:s3_mybucket');
    
    +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | SYSTEM$GET_AWS_SNS_IAM_POLICY('ARN:AWS:SNS:US-WEST-2:001234567890:S3_MYBUCKET')                                                                                                                                                                   |
    +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | {"Version":"2012-10-17","Statement":[{"Sid":"1","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789001:user/vj4g-a-abcd1234"},"Action":["sns:Subscribe"],"Resource":["arn:aws:sns:us-west-2:001234567890:s3_mybucket"]}]}                 |
    +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    
    Copy
  6. 返回 AWS 管理控制台。从左侧导航窗格中选择 Topics

  7. 选择您的 S3 桶的主题,然后点击 Edit 按钮。Edit 页面随即打开。

  8. 点击 Access policy - Optional 以展开页面的此区域。

  9. 将 SYSTEM$GET_AWS_SNS_IAM_POLICY 函数结果中添加的 IAM 策略合并到 JSON 文档中。

    例如:

    原始 IAM 策略(缩写):

    {
      "Version":"2008-10-17",
      "Id":"__default_policy_ID",
      "Statement":[
         {
            "Sid":"__default_statement_ID",
            "Effect":"Allow",
            "Principal":{
               "AWS":"*"
            }
            ..
         }
       ]
     }
    
    Copy

    合并的 IAM 策略:

    {
      "Version":"2008-10-17",
      "Id":"__default_policy_ID",
      "Statement":[
         {
            "Sid":"__default_statement_ID",
            "Effect":"Allow",
            "Principal":{
               "AWS":"*"
            }
            ..
         },
         {
            "Sid":"1",
            "Effect":"Allow",
            "Principal":{
              "AWS":"arn:aws:iam::123456789001:user/vj4g-a-abcd1234"
             },
             "Action":[
               "sns:Subscribe"
             ],
             "Resource":[
               "arn:aws:sns:us-west-2:001234567890:s3_mybucket"
             ]
         }
       ]
     }
    
    Copy
  10. 添加额外的策略授权以允许 S3 将桶的事件通知发布到 SNS 主题。

    例如(使用 SNS 主题 ARN 以及这些说明中使用的 S3 桶):

    {
        "Sid":"s3-event-notifier",
        "Effect":"Allow",
        "Principal":{
           "Service":"s3.amazonaws.com"
        },
        "Action":"SNS:Publish",
        "Resource":"arn:aws:sns:us-west-2:001234567890:s3_mybucket",
        "Condition":{
           "ArnLike":{
              "aws:SourceArn":"arn:aws:s3:*:*:s3_mybucket"
           }
        }
     }
    
    Copy

    合并的 IAM 策略:

    {
      "Version":"2008-10-17",
      "Id":"__default_policy_ID",
      "Statement":[
         {
            "Sid":"__default_statement_ID",
            "Effect":"Allow",
            "Principal":{
               "AWS":"*"
            }
            ..
         },
         {
            "Sid":"1",
            "Effect":"Allow",
            "Principal":{
              "AWS":"arn:aws:iam::123456789001:user/vj4g-a-abcd1234"
             },
             "Action":[
               "sns:Subscribe"
             ],
             "Resource":[
               "arn:aws:sns:us-west-2:001234567890:s3_mybucket"
             ]
         },
         {
            "Sid":"s3-event-notifier",
            "Effect":"Allow",
            "Principal":{
               "Service":"s3.amazonaws.com"
            },
            "Action":"SNS:Publish",
            "Resource":"arn:aws:sns:us-west-2:001234567890:s3_mybucket",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:*:s3_mybucket"
               }
            }
          }
       ]
     }
    
    Copy
  11. 点击 Save changes 按钮。

第 2 步:创建包含目录表的暂存区

使用 CREATE STAGE 命令创建引用您的 S3 桶的外部暂存区。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>' ]
Copy

其中:

directoryTable (for Amazon S3) ::=
  [ DIRECTORY = ( ENABLE = { TRUE | FALSE }
                  [ AUTO_REFRESH = { TRUE | FALSE } ]
                  [ AWS_SNS_TOPIC = '<sns_topic_arn>' ] ) ]
Copy

目录表参数 (directoryTable)

ENABLE = TRUE | FALSE

指定是否向暂存区添加目录表。当值为 TRUE 时,将创建包含暂存区的目录表。

默认:FALSE

AUTO_REFRESH = TRUE | FALSE

指定当 新的或更新的 数据文件在 URL 值中指定的命名外部暂存区中可用时,Snowflake 是否应支持触发目录表元数据自动刷新。

TRUE

Snowflake 支持触发目录表元数据自动刷新。

FALSE

Snowflake 不支持触发目录表元数据自动刷新。必须使用 ALTER STAGE ... REFRESH 定期手动刷新目录表元数据,以使元数据与暂存区路径中的当前文件列表同步。

默认:FALSE

Amazon S3

AWS_SNS_TOPIC = '<sns_topic_arn>'

为 S3 桶的 SNS 主题指定 ARN。CREATE 目录表语句会将 Snowflake SQS 队列订阅至 SNS 主题。

以下示例会在活动架构中为用户会话创建一个名为 mystage 的暂存区。云存储 URL 包括路径 files。该暂存区引用名为 my_storage_int 的存储集成。

USE SCHEMA mydb.public;
Copy
CREATE STAGE mystage
  URL='s3://load/files/'
  STORAGE_INTEGRATION = my_storage_int
  DIRECTORY = (
    ENABLE = true
    AUTO_REFRESH = true
    AWS_SNS_TOPIC = 'arn:aws:sns:us-west-2:001234567890:s3_mybucket'
  );
Copy

将新的或更新的数据文件添加到云存储位置时,事件通知会通知 Snowflake 将它们扫描到目录表元数据中。

第 3 步:手动刷新目录表元数据

使用 ALTER STAGE 命令手动刷新目录表中的元数据。

ALTER STAGE [ IF EXISTS ] <name> REFRESH [ SUBPATH = '<relative-path>' ]
Copy

其中:

REFRESH

访问目录表定义中引用的暂存数据文件并更新表元数据:

  • 路径中的新文件将添加到表元数据中。

  • 对路径中文件的更改将在表元数据中更新。

  • 路径中不再存在的文件将从表元数据中移除。

目前,每次将文件添加到暂存区、更新或删除文件时,都需要执行此命令。此步骤将元数据与目录表的暂存区定义中的最新关联文件集同步。

SUBPATH = '<relative-path>'

(可选)指定相对路径以刷新数据文件的特定子集的元数据。

例如,在名为 mystage 的暂存区中手动刷新目录表元数据:

ALTER STAGE mystage REFRESH;
Copy

重要

如果在创建目录表后至少一次未成功完成此步骤,则在通知事件触发目录表元数据首次自动刷新之前,查询目录表不会返回任何结果。

第 4 步:配置安全性

对于将用于查询目录表的每个附加角色,请使用 GRANT <privileges> 授予对各种对象(即数据库、架构、暂存区和表)的足够的访问控制权限:

对象

权限

备注

数据库

USAGE

架构

USAGE

命名暂存区

USAGE、READ

命名文件格式

USAGE

语言: 中文