概要
本記事では、Snowflake Catalog の全体像を理解するための学習コンテンツを紹介します。Snowflake Catalog を実際に検証する際には外部サービスとの連携が必要ですが、ここでは主に Google Colab 上で Spark を利用した操作手順を中心に解説します。本記事を通じて、Snowflake Catalog についての理解が深まれば幸いです。
- 環境構築
- Azure Stroage 環境の構築
- Snowflake 環境での事前準備
- 外部ボリュームの作成
- Snowflake 上での Snowflake-managed Iceberg テーブルの操作
- テーブル作成
- データロード
- クエリの実行
- Snowflake Catalog SDK による Spark からの接続
- Open Catalog への同期
- Snowflake Open Catalog 環境の準備
- 既存の Iceberg テーブルを Snowflake Open Catalog に同期
- テーブル作成時に Snowflake Open Catalog へ同期
Snowflake Open Catalog での学習コンテンツについては、以下の記事をご参照ください。
出所:Snowflake Open Catalog における Iceberg テーブルの基本的な操作手順 #Spark - Qiita
Snowflake Catalog について
Snowflake Catalog は、Snowflake が内部で提供する Apache Iceberg™ REST プロトコル による Apache Iceberg のテーブルカタログ機能です。
出所:Apache Iceberg™ テーブル | Snowflake Documentation
Snowflake 上で Apache Iceberg を利用する方法としては、以下の 2 つがあります。
- Snowflake をカタログとして利用(Snowflake Catalog)
- Snowflake Open Catalog(マネージド Apache Polaris)を利用
本記事は主に前者の Snowflake Catalog に関する手順を解説します。なお、Snowflake Catalog 上で管理しているテーブルを Snowflake Open Catalog に同期させることも可能です。
出所:Snowflakeオープンカタログをはじめるにあたり | Snowflake Documentation
本記事の内容は Snowflake の公式チュートリアルをベースにしています。下記の公式チュートリアルも併せてご確認ください。
また、Google Colab 上で Spark を操作するための基本的な手順は、以下の記事をご参照ください。
環境構築
Azure Storage 環境の構築
まず、Azure Storage アカウントを作成します。
snowflake
という名前のコンテナーを作成します。
snowflakecatalog
というディレクトリを作成します。
検証用のデータベースを作成
CREATE OR REPLACE DATABASE SNOWFLAKE_CATALOG_TUTORIAL_DB;
USE DATABASE SNOWFLAKE_CATALOG_TUTORIAL_DB;
外部 Volume を作成
CREATE EXTERNAL VOLUME
文は変数を直接使用できないため、設定値を生成してコピー&ペーストします。まずは必要な値を変数に格納します。
-- 各値を変数としてセット
SET azure_tenant_id = '095ca098-c723-478f-xxxx-xxxxx';
SET azure_storage_account_name = 'snowflakeicebergqiita';
SET storage_provider = 'AZURE';
-- 連結した URL は変数に事前に設定
SET full_storage_uri = 'azure://' || $azure_storage_account_name || '.blob.core.windows.net/snowflake/snowflakecatalog/';
SELECT
$storage_provider AS STORAGE_PROVIDER
,$full_storage_uri AS STORAGE_BASE_URL
,$azure_tenant_id AS AZURE_TENANT_ID;
上記のクエリで取得した値を参考に、下記の CREATE EXTERNAL VOLUME
文をコピー&ペーストして実行します。
-- 外部 Volume を作成
CREATE OR REPLACE EXTERNAL VOLUME my_azure_sf_volume
STORAGE_LOCATIONS = (
(
NAME = 'my-azure-sf-container'
STORAGE_PROVIDER = 'AZURE'
STORAGE_BASE_URL = 'azure://snowflakeicebergqiita.blob.core.windows.net/snowflake/snowflakecatalog/'
AZURE_TENANT_ID = '095ca098-c723-478f-xxxx-xxxxx'
)
)
ALLOW_WRITES = true;
作成した Volume を確認します。
DESC EXTERNAL VOLUME my_azure_sf_volume;
外部 Volume に対する権限の付与
次に、AZURE_CONSENT_URL
の URL を Azure にログインしているブラウザで開き、Snowflake からのアクセス許可を付与します。
DESC EXTERNAL VOLUME my_azure_sf_volume;
SELECT
PARSE_JSON($4):AZURE_MULTI_TENANT_APP_NAME::string AS AZURE_MULTI_TENANT_APP_NAME,
PARSE_JSON($4):AZURE_CONSENT_URL::string AS AZURE_CONSENT_URL
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
WHERE $2 = 'STORAGE_LOCATION_1';
承諾
を選択します。
Azure Storage 側で AZURE_MULTI_TENANT_APP_NAME
のアンダーバーより前のアプリケーション(例:ps27tlsnowflakepacint
)を検索し、適切なロールを付与します。
本記事は Azure 環境向けの手順を示していますが、Snowflake のドキュメントにはクラウドベンダー別の手順が用意されています。
Snowflake 上での Snowflake-managed Iceberg テーブル操作
テーブル作成
CREATE OR REPLACE ICEBERG TABLE customer_iceberg (
c_custkey INTEGER,
c_name STRING,
c_address STRING,
c_nationkey INTEGER,
c_phone STRING,
c_acctbal INTEGER,
c_mktsegment STRING,
c_comment STRING
)
CATALOG = 'SNOWFLAKE'
EXTERNAL_VOLUME = 'my_azure_sf_volume'
BASE_LOCATION = 'customer_iceberg';
SHOW TABLES IN DATABASE SNOWFLAKE_CATALOG_TUTORIAL_DB
以下のように metadata file
を確認し、00000
になっていることを確認します。
SELECT SYSTEM$GET_ICEBERG_TABLE_INFORMATION('CUSTOMER_ICEBERG');
データロード
INSERT INTO customer_iceberg
SELECT * FROM snowflake_sample_data.tpch_sf1.customer;
再度 metadata file
を確認すると、00001
に更新されています。
SELECT SYSTEM$GET_ICEBERG_TABLE_INFORMATION('CUSTOMER_ICEBERG');
クエリの実行
SELECT
*
FROM
customer_iceberg
LIMIT 10;
DELETE の実施
DELETE FROM CUSTOMER_ICEBERG
WHERE c_mktsegment = 'AUTOMOBILE';
SELECT * FROM CUSTOMER_ICEBERG WHERE c_mktsegment = 'AUTOMOBILE';
再度 metadata file
を確認すると、00002
に更新されています。
SELECT SYSTEM$GET_ICEBERG_TABLE_INFORMATION('CUSTOMER_ICEBERG');
Snowflake Catalog SDK により Spark から接続
Azure Storage で アクセスキー
タブにある key1
の値を取得
Google Colab のノートブックを作成
Spark のバージョンを確認
!pyspark --version
Snowflake の account_identifier と認証情報を変数にセット
# Snowflake
account_identifier = "MTIRXWM-ZJA50722"
user_name = "MANABIAN"
password = "3-g!qNmm9uXXXXX"
Azure Storage の名称とキーを変数にセット
# Azure Storage に関する情報をセット
azure_storage_account_name = "snowflakeicebergqiita"
azure_storage_account_key = "cBGfLSEInUgJ+e6w/bx7x4yewwOqDIIGE7sjPUMttki9CzXXXXXXXX=="
SparkSession の定義と疎通確認
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.8.1,"
"net.snowflake:snowflake-jdbc:3.23.0,"
"org.apache.hadoop:hadoop-azure:3.2.0"
)
.config("spark.sql.defaultCatalog", "snowflake_catalog")
.config("spark.sql.catalog.snowflake_catalog", "org.apache.iceberg.spark.SparkCatalog")
.config("spark.sql.catalog.snowflake_catalog.catalog-impl", "org.apache.iceberg.snowflake.SnowflakeCatalog")
.config("spark.sql.catalog.snowflake_catalog.uri", f"jdbc:snowflake://{account_identifier}.snowflakecomputing.com")
.config("spark.sql.catalog.snowflake_catalog.jdbc.user", user_name)
.config("spark.sql.catalog.snowflake_catalog.jdbc.password", password)
.config("spark.sql.catalog.snowflake_catalog.io-impl", "org.apache.iceberg.hadoop.HadoopFileIO")
.config(f"spark.hadoop.fs.azure.account.key.{azure_storage_account_name}.blob.core.windows.net", azure_storage_account_key)
.getOrCreate()
)
spark
spark.sql("SHOW NAMESPACES").show(truncate=False)
テーブルのデータを取得
df = (
spark.read
.format("iceberg")
.option("vectorization-enabled", "false")
.table("SNOWFLAKE_CATALOG_TUTORIAL_DB.PUBLIC.CUSTOMER_ICEBERG")
)
df.limit(10).show(truncate=False)
Snowflake Open Catalog への自動同期
Snowflake Open Catalog 環境の準備
Snowflake Open Catalog のアカウントを作成
まず、ORGADMIN
ロールに切り替えます。
-- ORGADMIN にカレントロールを変更
USE ROLE ORGADMIN;
SELECT CURRENT_ROLE();
次に、Snowflake Open Catalog が有効なアカウントを新規作成します。
-- Snowflake Open Catalog が有効な Snowflake アカウントを作成
-- ToDo EMAIL と REGION を変更する必要あり
CREATE ACCOUNT manabian_opencatalog_00_account
ADMIN_NAME = 'opencatalog_admin'
ADMIN_PASSWORD = 'MySecurePassword2025!'
EMAIL = 'admin@example.com'
MUST_CHANGE_PASSWORD = FALSE
EDITION = ENTERPRISE
REGION = 'AZURE_EASTUS2'
POLARIS = TRUE;
Snowflake Open Catalog アカウントの URL を取得します。
-- カウントの URL を取得
SHOW ACCOUNTS LIKE 'manabian_opencatalog_00_account';
作成直後はアクセスすると 404 エラーが出る場合があるので、5 分ほど待ちます。
待機後、設定したアカウントでログインし、Snowflake Open Catalog のページに接続できることを確認します。
外部カタログの作成
Snowflake Open Catalog 上部メニューの Catalogs
タブを開き、+ Catalog
をクリックします。
カタログの設定
# | 項目 | 設定値例 | 備考 |
---|---|---|---|
1 | Name | manabian_sf_sync_catalog | カタログの名称 |
2 | External | チェック | 外部カタログとして扱うかどうか |
3 | Storage provider | Azure | |
4 | Default base location | wasbs://snowflake@snowflakeicebergqiita.blob.core.windows.net/snowflakecatalog/ |
Azure プロトコルではなく、 wasbs または abfss を指定 |
5 | Additional locations (optional) | 空文字 | |
6 | Azure tenant ID | 095ca098-c723-xxxxxx-xxxxxxxxxx | Azure テナント ID |
本記事は Azure 環境を例に示していますが、以下の公式ドキュメントでは各クラウドベンダー向けの手順が案内されています。
出所:Azureストレージを使用したカタログの作成| Snowflake Documentation
カタログが作成されていることを確認します。
Azure Storage に対する認証設定
AZURE_CONSENT_URL
にアクセスし、外部アプリケーションに対してログインの同意を行います。
この手順は、以下ドキュメントにおける「Microsoft ID プラットフォームでのアクセス許可と同意の設定」に相当します。
Azure ポータルでロール割り当て
Azure Storage のページで アクセス制御 (IAM)
-> + 追加
-> ロールの割り当ての追加
を選択します。
ストレージ BLOB データ共同作成者
を選択し、次へ
をクリックします。
Snowflake Open Catalog のカタログ設定で確認した AZURE_MULTI_TENANT_APP_NAME
のうち、アンダーバーより前にある名称(例:mjonvmsnowflakepacint
)で検索し、選択します。
Snowflake Open Catalog のカタログ設定に記載されている AZURE_MULTI_TENANT_APP_NAME
を参照してください。
最後に レビューと割り当て
をクリックし、Role assignments
タブで割り当てが追加されたことを確認します。
Snowflake Open Catalog 上でのロール作成
Snowflake Open Catalog にて、Connections
-> Roles
-> + Principal Role
を選択します。
Name
に snowflake_role
と入力し、Create
をクリックします。
Snowflake Open Catalog 上での接続情報作成
同じく Connections
-> Principal
-> + Connection
を選択します。
項目に値を入力し、Create
をクリックします。
# | 項目 | 設定値例 |
---|---|---|
1 | Name | snowflake |
2 | Query Engine | snowflake |
3 | Principal Role | snowflake_role |
Snowflake からのアクセス時に使用する Client ID
と Client Secret
を取得します。
Snowflake Open Catalog のカタログに対する権限付与
Catalogs
-> 対象のカタログ -> Roles
-> + Catalog Role
を選択します。
以下の項目を設定し、Create
をクリックします。
# | 項目 | 設定値例 |
---|---|---|
1 | Name | snowflake_catalog_role |
2 | Privileges | CATALOG_MANAGE_CONTENT |
Grant to Principal Role
をクリックします。
次の設定を行い、Grant
をクリックします。
# | 項目 | 設定値例 |
---|---|---|
1 | Catalog role to grant | snowflake_catalog_role |
2 | Grant to Principal | snowflake_role |
Snowflake Open Catalog のカタログ統合を作成
-- 各値を変数としてセット
SET open_catalog_account_identifier = 'mtirxwm-manabian_opencatalog_00_account';
SET catalog_name = 'manabian_sf_sync_catalog';
SET client_id = 'OmD7CNsfKOeqt8jAe4QXXXXXX=';
SET client_secret = 'hCfWMmj+b4T5DJvI/uyxXXXXXXX=';
-- 連結した URL は変数に事前に設定
SET full_catalog_uri = 'https://' || $open_catalog_account_identifier || '.snowflakecomputing.com/polaris/api/catalog';
-- 変数を利用してカタログ統合を作成
CREATE OR REPLACE CATALOG INTEGRATION demo_open_catalog_ext
CATALOG_SOURCE = POLARIS
TABLE_FORMAT = ICEBERG
CATALOG_NAMESPACE='default'
REST_CONFIG = (
CATALOG_URI = $full_catalog_uri
WAREHOUSE = $catalog_name
)
REST_AUTHENTICATION = (
TYPE = OAUTH
OAUTH_CLIENT_ID = $client_id
OAUTH_CLIENT_SECRET = $client_secret
OAUTH_ALLOWED_SCOPES = ('PRINCIPAL_ROLE:ALL')
)
ENABLED = true;
既存の Iceberg テーブルを Snowflake Open Catalog に同期
ALTER ICEBERG TABLE CUSTOMER_ICEBERG SET
CATALOG_SYNC = 'demo_open_catalog_ext';
Snowflake Open Catalog で該当テーブルが表示されることを確認します。
テーブル作成時にテーブルを Snowflake Open Catalog に同期
テーブル作成時に CATALOG_SYNC
オプションを指定します。
CREATE OR REPLACE ICEBERG TABLE nation_iceberg (
n_nationkey INTEGER,
n_name STRING
)
CATALOG = 'SNOWFLAKE'
EXTERNAL_VOLUME = 'my_azure_sf_volume'
BASE_LOCATION = 'nation_iceberg'
CATALOG_SYNC = 'demo_open_catalog_ext'
AS SELECT
N_NATIONKEY,
N_NAME
FROM
snowflake_sample_data.tpch_sf1.nation;
Snowflake Open Catalog で新たに作成したテーブルが確認できれば完了です。