Snowflake Open Catalog 入门

概述

Snowflake Open Catalog 是 Apache Iceberg™ 的 Open Catalog。Open Catalog 作为一项在 Snowflake 上管理的 SaaS 服务提供。它也可以作为开源代码提供,您可以自己构建和部署。 Open Catalog 通过基于角色的访问控制提供具有跨引擎安全性的 Apache Iceberg REST 目录的实现。

在本教程中,您将学习如何开始使用在 Snowflake 上管理的 Open Catalog。

您将学习以下内容

  • 如何创建新的 Open Catalog 账户。

  • 如何在 Open Catalog 账户中创建新的 Iceberg 目录并使用 RBAC 进行保护。

  • 如何使用 Apache Spark™ 在目录中创建表并运行查询。

  • 如何使用 Snowflake 对目录中的表运行查询。

  • 如何将 Snowflake 中的托管 Iceberg 表镜像或发布到 Open Catalog。

您需要的权限

  • 您的 Snowflake 组织中的 ORGADMIN 权限(用于创建新的 Open Catalog 账户)。

  • 您的 Snowflake 账户中的 ACCOUNTADMIN 权限(用于连接 Open Catalog 账户)。此 Snowflake 账户不必与 Snowflake 组织账户相同。

您会做什么

您将完成两个用例:

  • 用例 1:在 Open Catalog 中创建目录,使用 Apache Spark 创建表,使用 Apache Spark 和 Snowflake 查询表。

    图片 1:图表

  • 用例 2:使用 Snowflake 在 Snowflake DB 账户中创建 Apache Iceberg 表,然后将其发布到 Open Catalog,这样 Apache Spark 就可以对其运行查询。

    图片 2:图表

设置环境

在笔记本电脑上安装 Conda、Spark 和 Jupyter

在本教程中,您可以使用 Conda 轻松创建开发环境和下载必要的软件包。只有当你按照用例 2 使用 Apache Spark™ 读取 Snowflake 管理的 Apache Spark™ 表时,才需要这样做。这不是在 Snowflake 上创建或使用 Iceberg 表所必需的。

  1. 要安装 Conda,请按照以下特定于您 OS 的说明进行安装:

    • Mac (https://docs.conda.io/projects/conda/en/latest/user-guide/install/macos.html)

    • Windows (https://docs.conda.io/projects/conda/en/latest/user-guide/install/windows.html)

    • Linux (https://docs.conda.io/projects/conda/en/latest/user-guide/install/linux.html)

  2. 使用以下内容创建名为 environment.yml 的文件:

    name: iceberg-lab
    channels:
      - conda-forge
    dependencies:
      - findspark=2.0.1
      - jupyter=1.0.0
      - pyspark=3.5.0
      - openjdk=11.0.13
    
    Copy
  3. 要创建所需的环境,请在 shell 中运行以下命令:

    conda env create -f environment.yml
    
    Copy

创建 Open Catalog 账户

Open Catalog 账户只能由 ORGADMIN 创建。

  1. 在 Snowsight 的导航窗格中,选择 Admin > Accounts

  2. + Account 下拉菜单中,选择 Create Snowflake Open Catalog Account

  3. 完成 Create Snowflake Open Catalog Account 对话框:

    • :您想要存储 Apache Iceberg™ 表的云提供商。

    • 区域:您要存储 Iceberg 表的地区。

    • 版本:您的 Open Catalog 账户的版本。

  4. 选择 Next

  5. 在 Create New Account 对话框中,填写 Account Name、User Name、Password 和 Email 字段。

  6. 选择 Create Account。您的新 Open Catalog 账户已创建,并出现确认框。

  7. 在确认框中,选择 Account Locator URL,在您的网络浏览器中打开账户定位器 URL。

  8. 将账户定位器 URL 加入书签。登录 Open Catalog 时,必须指定账户定位器 URL。

登录到 Open Catalog Web 界面

  1. 创建账户后,点击您通过电子邮件收到的账户 URL,OR前往 https://app.snowflake.cn

  2. 点击 Sign into a different account,然后使用之前创建的 Open Catalog 账户登录。

用例 1:使用 Apache Spark™ 创建表

创建授予对 S3 位置的访问权限的 IAM 策略

如果您还没有,请首先创建一项授予访问您的 S3 位置的权限的 IAM 策略。有关创建此策略的说明,请参阅 创建授予您的 S3 位置访问权限的 IAM 策略

创建 IAM 角色

如果您还没有,请为 Open Catalog 创建一个 AWS IAM 角色来授予您的 S3 存储桶权限。有关说明,请参阅 创建 IAM 角色。当说明提示您选择策略时,选择授予访问您的 S3 位置的 IAM 策略。

在 Open Catalog 中创建内部目录

您可以在 Open Catalog 账户中使用内部目录来创建表、进行查询,并使用 Apache Spark™ 或其他查询引擎对表运行 DML。

  1. 登录您的新 Open Catalog 账户。

  2. 要创建新目录,请在左侧窗格中选择 Catalogs

  3. 选择右上角的 +Catalogs

  4. Create Catalog 对话框中,输入以下详细信息:

    • Default base location: 存储表格数据的位置。

    • Additional locations (optional): 以逗号分隔的多个存储位置列表。它主要用于需要从该目录中的不同位置导入表。您可以把它留空。

    • S3 role ARN: 对存储位置具有读写权限的 AWS 角色。输入您为 Open Catalog 创建的 IAM 角色的 ARN。

    • External ID:(可选): 在目录用户和存储账户之间创建信任关系时要提供的密钥。 如果您跳过此操作,它将自动生成。在本教程中使用像 abc123 这样的简单字符串。

  5. 选择 Create。您的目录已创建并将以下值添加到您的目录中:

    • 您的 Open Catalog 账户的 IAM 用户 arn

    • 如果您没有自己输入 External ID,则会为您的目录自动生成一个 External ID

    在下一节中创建信任关系时,您将需要这些值。

创建信任关系

创建目录后,您需要设置信任关系,以便上述配置中指定的 S3 角色可以在存储位置读取和写入数据。请注意,要完成此任务,您需要为您的目录提供 S3 IAM 用户 arn 和 External ID。

  1. 创建目录后,在列表中选择您的目录以显示您的目录的 S3 IAM 用户 arn 和 External ID。

  2. 要创建信任关系,请按照 第 5 步:授予访问桶对象的 IAM 用户权限 中的说明操作。

    在这些说明中显示的 JSON 对象中:

    • 对于 <open_catalog_user_arn>,使用 Open Catalog UI 中 IAM 用户 arn 下的值。

    • 对于 <open_catalog_external_id>,使用 Open Catalog UI 中 External ID 下的值。

    屏幕截图显示 Open Catalog 中的内部目录和 AWS IAM 角色的策略文档。

为 Apache Spark™ 创建新连接

为 Apache Spark 创建一个新连接 (client_id/client_secret pair),以便对您刚创建的目录运行查询。

  1. 在 Open Catalog 的左侧窗格中,选择 Connections 选项卡,然后选择右上角的 + Connections

  2. Configure Service Connection 对话框中,创建新的主体角色或从可用角色中选择一个。

  3. 选择 Create

  4. Configure Service Connection 对话框中,要将客户端 ID 和客户端密钥复制到文本编辑器,请在 As <CLIENT ID>:<SECRET> 字段中选择 Copy

    重要

    以后您将无法从 Open Catalog 服务检索这些文本字符串,因此必须立即复制它们。配置 Spark 时可以使用这些文本字符串。

为连接设置目录权限

现在,您可以为服务连接授予权限,以便它可以访问目录。如果没有访问权限,服务连接将无法对目录运行任何查询。

  1. 在导航窗格中,选择 Catalogs,然后在列表中选择您的目录。

  2. 要创建新角色,请选择 Roles 选项卡。

  3. 选择 + Catalog role

  4. Create Catalog Role 对话框中,为 Name 输入 spark_catalog_role

  5. 对于 Privileges,选择 **CATALOG_MANAGE_CONTENT **,然后选择 Create

    这为角色提供了创建、读取和写入表的权限。

  6. 选择 Grant to Principal Role

  7. Grant Catalog Role 对话框中,对于 Principal role to receive grant,请选择 my_spark_admin_role

  8. 对于 Catalog role to grant,选择 spark_catalog_role,然后选择 Grant

此过程的结果是,角色 spark_catalog_role 被授予了 my_spark_admin_role,这为您在前面的过程中创建的 Spark 连接提供了管理员权限。

设置 Spark

在终端上运行以下命令以激活您在安装程序中创建的虚拟环境,然后打开 Jupyter Notebook:

conda activate iceberg-lab
jupyter notebook
Copy

配置 Spark

要配置 Spark,请在 Jupyter Notebook 中运行这些命令。

有关更多信息,包括参数描述,请参阅 在 Spark 中注册服务连接

import os
os.environ['SPARK_HOME'] = '/Users/<username>/opt/anaconda3/envs/iceberg-lab/lib/python3.12/site-packages/pyspark'

import pyspark
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName('iceberg_lab') \
.config('spark.jars.packages', 'org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.4.1,software.amazon.awssdk:bundle:2.20.160,software.amazon.awssdk:url-connection-client:2.20.160') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.config('spark.sql.defaultCatalog', 'opencatalog') \
.config('spark.sql.catalog.opencatalog', 'org.apache.iceberg.spark.SparkCatalog') \
.config('spark.sql.catalog.opencatalog.type', 'rest') \
.config('spark.sql.catalog.opencatalog.header.X-Iceberg-Access-Delegation','vended-credentials') \
.config('spark.sql.catalog.opencatalog.uri','https://<open_catalog_account_identifier>.snowflakecomputing.cn/polaris/api/catalog') \
.config('spark.sql.catalog.opencatalog.credential','<client_id>:<client_secret>') \
.config('spark.sql.catalog.opencatalog.warehouse','<catalog_name>') \
.config('spark.sql.catalog.opencatalog.scope','PRINCIPAL_ROLE:<principal_role_name>') \
.getOrCreate()

#Show namespaces
spark.sql("show namespaces").show()

#Create namespace
spark.sql("create namespace spark_demo")

#Use namespace
spark.sql("use namespace spark_demo")

#Show tables; this will show no tables since it is a new namespace
spark.sql("show tables").show()

#create a test table
spark.sql("create table test_table (col1 int) using iceberg");

#insert a record in the table
spark.sql("insert into test_table values (1)");

#query the table
spark.sql("select * from test_table").show();
Copy

可选:S3 跨区域

当您的 Open Catalog 账户托管在 Amazon S3 上,但与 S3 存储桶所在区域相比位于不同的区域时,您必须提供额外的 Spark 配置设置:

.config('spark.sql.catalog.opencatalog.client.region','<target_s3_region>') \
Copy

<target_s3_region> 指定您的 S3 存储桶所在的区域。有关区域代码列表,请参阅 AWS 文档中的 [区域终端节点] (https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints)。

修改了以下代码示例以包含 s3 区域:

import pyspark
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName('iceberg_lab') \
.config('spark.jars.packages', 'org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.4.1,software.amazon.awssdk:bundle:2.20.160,software.amazon.awssdk:url-connection-client:2.20.160') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.config('spark.sql.defaultCatalog', 'opencatalog') \
.config('spark.sql.catalog.opencatalog', 'org.apache.iceberg.spark.SparkCatalog') \
.config('spark.sql.catalog.opencatalog.type', 'rest') \
.config('spark.sql.catalog.opencatalog.header.X-Iceberg-Access-Delegation','vended-credentials') \
.config('spark.sql.catalog.opencatalog.uri','https://<open_catalog_account_identifier>.snowflakecomputing.cn/polaris/api/catalog') \
.config('spark.sql.catalog.opencatalog.credential','<client_id>:<secret>') \
.config('spark.sql.catalog.opencatalog.warehouse','<catalog_name>') \
.config('spark.sql.catalog.opencatalog.scope','PRINCIPAL_ROLE:<principal_role_name>') \
.config('spark.sql.catalog.opencatalog.client.region','<target_s3_region>') \
.getOrCreate()
Copy

使用 Snowflake 查询表

你可以在 Snowflake 中创建目录集成对象,然后在 Snowflake 中创建一个 Apache Iceberg™ 表,用于表示 Open Catalog 中的表。在以下示例中,您在 Snowflake 中创建了一个 Iceberg 表,该表表示 Spark 刚刚在 Open Catalog 的内部目录中创建的 Iceberg 表。

您可以使用相同的 Spark 连接凭据,也可以创建新的 Snowflake 连接。如果您创建新连接,则必须相应地设置角色和权限。

  1. 创建目录集成对象:

    CREATE OR REPLACE CATALOG INTEGRATION demo_open_catalog_int 
    CATALOG_SOURCE=POLARIS 
    TABLE_FORMAT=ICEBERG 
    CATALOG_NAMESPACE='<catalog_namespace>' 
    REST_CONFIG = (
    CATALOG_URI ='https://<orgname>.<my-snowflake-open-catalog-account-name>.snowflakecomputing.com/polaris/api/catalog' 
    WAREHOUSE = <catalog_name>
    )
    REST_AUTHENTICATION = (
    TYPE=OAUTH 
    OAUTH_CLIENT_ID='<client_id>' 
    OAUTH_CLIENT_SECRET='<secret>' 
    OAUTH_ALLOWED_SCOPES=('PRINCIPAL_ROLE:ALL') 
    ) 
    ENABLED=true;
    
    # the <catalog_namespace> created in previous step is spark_demo.
    # the <catalog_name> created in previous step is demo_catalog.
    
    Copy
  2. 使用上面创建的目录集成在 Snowflake 中创建表表示形式,然后查询该表:

    create or replace iceberg table test_table
      catalog = 'demo_open_catalog_int'
      external_volume = '<external_volume>'
      catalog_table_name = 'test_table'
    
    select * from test_table;
    
    Copy

用例 2:将 Apache Iceberg™ 表从 Snowflake 同步到 Open Catalog

如果您在 Snowflake 中有 Iceberg 表,你可以将它们同步到 Open Catalog,这样其他引擎就可以查询这些表。

在 Open Catalog 中创建外部目录

Snowflake 的 Iceberg 表可以在您的 Open Catalog 账户的外部目录中同步。

  1. 登录您的新 Open Catalog 账户。

  2. 要创建新目录,请在左侧窗格中选择 Catalogs

  3. 选择右上角的 +Catalogs

  4. Create Catalog 对话框中,输入以下详细信息:

    • Name:为目录命名 demo_catalog_ext

    • External 的开关设置为 On

    • Default base location: 存储表格数据的位置。

      注意

      与在本教程的用例 1 中创建的内部目录相比,必须使用不同的存储位置。为确保正确执行为目录定义的访问权限,两个不同的目录的位置不能重叠。

    • Additional locations (optional): 以逗号分隔的多个存储位置列表。它主要用于需要从该目录中的不同位置导入表。您可以把它留空。

    • S3 role ARN: 对存储位置具有读写权限的 AWS 角色。

    • External ID:(可选): 在目录用户和存储账户之间创建信任关系时要提供的密钥。 如果您跳过此操作,它将自动生成。在本教程中使用像 abc123 这样的简单字符串。

  5. 选择 Create。以下值将添加到您的目录中:

    • 您的 Open Catalog 账户的 IAM 用户 arn

    • 如果您没有自己输入 External ID,则会为您的目录自动生成一个 External ID

为 Snowflake 创建连接

  1. 在 Open Catalog 的左侧窗格中,选择 Connections 选项卡,然后选择右上角的 + Connections

  2. Configure Service Connection 对话框中,创建新的主体角色或从可用角色中选择一个。

  3. 选择 Create

  4. Configure Service Connection 对话框中,要将客户端 ID 和客户端密钥复制到文本编辑器,请在 As <CLIENT ID>:<SECRET> 字段中选择 Copy

    重要

    以后您将无法从 Open Catalog 服务检索这些文本字符串,因此必须立即复制它们。配置 Spark 时可以使用这些文本字符串。

设置目录权限

要设置外部目录的权限,以便 Snowflake 连接具有对外部目录的正确权限,请执行以下步骤:

  1. 在导航窗格中,选择 Catalogs,然后在列表中选择您的外部目录。

  2. 要创建新角色,请选择 Roles 选项卡。

  3. 选择 + Catalog role

  4. Create Catalog Role 对话框中,为 Name 输入 spark_catalog_role

  5. 对于 Privileges,选择 **CATALOG_MANAGE_CONTENT **,然后选择 Create

    这为角色提供了创建、读取和写入表的权限。

  6. 选择 Grant to Principal Role

  7. Grant Catalog Role 对话框中,对于 Principal role to receive grant,请选择 my_spark_admin_role

  8. 对于 Catalog role to grant,选择 spark_catalog_role,然后选择 Grant

在 Snowflake 中创建目录集成对象

  1. 在 Snowflake 中,使用 CREATECATALOGINTEGRATION(Snowflake Open Catalog) 命令 创建目录集成对象:

    CREATE OR REPLACE CATALOG INTEGRATION demo_open_catalog_ext 
      CATALOG_SOURCE=POLARIS 
      TABLE_FORMAT=ICEBERG 
      CATALOG_NAMESPACE='default' 
      REST_CONFIG = (
        CATALOG_URI ='https://<orgname>.<my-snowflake-open-catalog-account-name>.snowflakecomputing.com/polaris/api/catalog' 
        WAREHOUSE = '<catalog_name>'
      )
      REST_AUTHENTICATION = (
        TYPE=OAUTH 
        OAUTH_CLIENT_ID='<client_id>' 
        OAUTH_CLIENT_SECRET='<secret>' 
        OAUTH_ALLOWED_SCOPES=('PRINCIPAL_ROLE:ALL') 
      ) 
      ENABLED=true;
    
    # the <catalog_name> created in previous step is demo_catalog_ext.
    
    Copy

    在这段代码中,每当修改 Snowflake 架构 polaris_demo.iceberg 中的托管 Iceberg 表时,它都会同步到 Open Catalog,这样其他引擎就可以查询这些表。

  2. 创建托管 Iceberg 表并将其从 Snowflake 同步到 Open Catalog。有关更多信息,请参阅:

    重要

    外部卷的 STORAGE_BASE_URL 必须与您在 Open Catalog 中创建的外部目录的 Default base location 相匹配。

    use database polaris_demo;
    use schema iceberg;
    
    # Note that the storage location for this external volume will be different than storage location for external volume in use case 1
    
    CREATE OR REPLACE EXTERNAL VOLUME snowflake_demo_ext
      STORAGE_LOCATIONS =
          (
            (
                NAME = '<storage_location_name>'
                STORAGE_PROVIDER = 'S3'
                STORAGE_BASE_URL = 's3://<s3_location>'
                STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::<aws_acct>:role/<rolename>'
                STORAGE_AWS_EXTERNAL_ID = '<external_id>'
            )
          );
    
    CREATE OR REPLACE ICEBERG TABLE test_table_managed (col1 int)
      CATALOG = 'SNOWFLAKE'
      EXTERNAL_VOLUME = 'snowflake_demo_ext'
      BASE_LOCATION = 'test_table_managed'
      CATALOG_SYNC = 'demo_open_catalog_ext'; 
    
    Copy

注意

如果表无法同步到 Open Catalog,请运行 SYSTEM$SEND_NOTIFICATIONS_TO_CATALOG 系统函数来诊断同步失败的原因。有关更多信息,请参阅 SYSTEM$SEND_NOTIFICATIONS_TO_CATALOG

结论

您可以在 Open Catalog 账户中使用内部目录来创建表、进行查询,并使用 Apache Spark™ 或其他查询引擎对表运行 DML。

在 Snowflake 中,您可以为 Open Catalog 创建目录集成以执行以下任务:

  • 在 Open Catalog 托管表上运行查询。

  • 将 Snowflake 表格同步到您的 Open Catalog 账户中的外部目录。

您学到的内容

  • 创建 Open Catalog 账户。

  • 在您的 Open Catalog 账户中创建内部目录。

  • 使用 Spark 在内部目录上创建表。

  • 使用 Snowflake 为 Open Catalog 创建目录集成,以便在 Open Catalog 账户的内部目录上创建的表上运行查询。

  • 在您的 Open Catalog 账户中创建外部目录。

  • 在 Snowflake 中创建托管的 Apache Iceberg™ 表,并将其同步到您的 Open Catalog 账户中的外部目录。

语言: 中文