概要
Snowflake on Google Cloud で管理している Snowflake-managed Apache Iceberg テーブルを、BigQuery の Apache Iceberg 用 BigLake 外部テーブルとして扱う方法を紹介します。Snowflake のデータを BigQuery に連携することなく、BigQuery から Snowflake と同等のデータを参照できるようになります。
BigQuery の Apache Iceberg 用 BigLake 外部テーブルは REST CATALOG をサポートしていないため、Snowflake-managed Apache Iceberg テーブルを Snowflake Open Catalog に同期しても、カタログ経由で最新のメタデータファイルを取得できません。そこで、Snowflake が提供する GET_ICEBERG_TABLE_INFORMATION
システム関数でテーブル情報を取得し、その取得結果に基づき BigQuery の Apache Iceberg 用 BigLake 外部テーブルを更新する手順を解説します。
出所:Apache Iceberg 用の BigLake 外部テーブルを作成する | BigQuery | Google Cloud
Apache Iceberg 用の BigLake 外部テーブルを、Google Colab で作成したデータから作成する手順を、以下の記事で紹介しています。Apache Iceberg 用の BigLake 外部テーブルを初めて作成する方は参考にしてみてください。
Snowflake における Apache Iceberg 機能の概要については、以下の記事で紹介しています。
Spark での Apache Iceberg テーブルの基本操作については、以下の記事で紹介しています。
- Getting started with PyIceberg と Iceberg で作成されるファイル郡の確認を Google Colab でやってみた #Python - Qiita
- Google Colab の Spark にて Hadoop Catalog の Apache Iceberg の動作検証 #iceberg - Qiita
事前準備
Snowflake on Google Cloud を作成
GCP_US_CENTRAL1
Snowflake と同一リージョンに GCS のバケットを作成
Snowflake を GCP_US_CENTRAL1
に作成したため、us-central1
リージョンにバケットを作成します。
バケット作成後、snowflake
というフォルダを作成します。
Snowflake における外部 Volume の構築
Snowflake にて外部 Volume を作成
CREATE OR REPLACE EXTERNAL VOLUME my_gcs_01_vol
STORAGE_LOCATIONS = (
(
NAME = 'my_gcs_bucket',
STORAGE_PROVIDER = 'GCS',
STORAGE_BASE_URL = 'gcs://manabianqiita/snowflake'
)
)
ALLOW_WRITES = TRUE;
外部 Volume に紐づくアカウントに対して GCS の権限を付与
DESC EXTERNAL VOLUME
の出力に含まれる STORAGE_GCP_SERVICE_ACCOUNT
の値を取得します。
DESC EXTERNAL VOLUME my_gcs_01_vol;
SELECT
PARSE_JSON($4):STORAGE_GCP_SERVICE_ACCOUNT::string AS STORAGE_GCP_SERVICE_ACCOUNT
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
WHERE $2 = 'STORAGE_LOCATION_1';
Google Cloud コンソールにて作成したバケットを選択し、PERMISSIONS
-> + GRANT ACCESS
を選択します。
STORAGE_GCP_SERVICE_ACCOUNT
の値を New principals
に貼り付け、適切な権限(例:Storage Admin
)を付与し、SAVE
を選択します。
Snowflake に戻り、外部 Volume の検証が成功することを確認します。
SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('my_gcs_01_vol');
Snowflake-managed Apache Iceberg テーブルを作成し BigQuery に登録
Snowflake-managed Apache 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_gcs_01_vol'
BASE_LOCATION = 'customer_iceberg'
AS
SELECT
60001 AS C_CUSTKEY,
'Customer#000060001' AS C_NAME,
'9Ii4zQn9cX' AS C_ADDRESS,
14 AS C_NATIONKEY,
'24-678-784-9652' AS C_PHONE,
9957.56 AS C_ACCTBAL,
'HOUSEHOLD' AS C_MKTSEGMENT,
'l theodolites boost slyly at the platelets: permanently ironic packages wake slyly pend' AS C_COMMENT;
SELECT * FROM customer_iceberg LIMIT 10;
GCS 上に Apache Iceberg テーブルのディレクトリが作成されていることを確認します。
BigQuery にて Apache Iceberg 用の BigLake 外部テーブルを作成
Snowflake でテーブルの最新のメタデータファイルのパスを取得します。Snowflake ではプロトコルが gcs
となっているため、gs
に修正する必要があります。
SELECT
JSON_EXTRACT_PATH_TEXT(
SYSTEM$GET_ICEBERG_TABLE_INFORMATION('CUSTOMER_ICEBERG'),
'metadataLocation'
) AS metadataLocation;
gcs://manabianqiita/snowflake/customer_iceberg/metadata/00001-7cdb0a89-9264-4347-8e7a-6804e039a6c8.metadata.json
Apache Iceberg 用の BigLake 外部テーブルを作成します。uris
には取得したパスを指定しつつ、gcs
を gs
に修正してください。
CREATE OR REPLACE EXTERNAL TABLE test.customer_iceberg
OPTIONS(
format = 'ICEBERG',
uris = ['gs://manabianqiita/snowflake/customer_iceberg/metadata/00001-7cdb0a89-9264-4347-8e7a-6804e039a6c8.metadata.json']
);
データが参照できることを確認します。
SELECT * FROM test.customer_iceberg;
Snowflake-managed Apache Iceberg テーブルの変更内容を BigQuery に反映
Snowflake-managed Apache Iceberg テーブルにデータを追加
INSERT INTO customer_iceberg
SELECT
60002,
'Customer#000060002',
'ThGBMjDwKzkoOxhz',
15,
'25-782-500-8435',
742.46,
'BUILDING',
'beans. fluffily regular packages'
UNION ALL
SELECT
60003,
'Customer#000060003',
'Ed hbPtTXMTAsgGhCr4HuTzK,Md2',
16,
'26-859-847-7640',
2526.92,
'BUILDING',
'fully pending deposits sleep quickly. blithely unusual accounts across the blithely bold requests are quickly';
Apache Iceberg 用の BigLake 外部テーブルのメタデータ更新
Snowflake でテーブルの最新のメタデータファイルのパスを再取得します。
SELECT
JSON_EXTRACT_PATH_TEXT(
SYSTEM$GET_ICEBERG_TABLE_INFORMATION('CUSTOMER_ICEBERG'),
'metadataLocation'
) AS metadataLocation;
gcs://manabianqiita/snowflake/customer_iceberg/metadata/00002-d56a73ad-6788-4b8e-bbd1-494f3db9913d.metadata.json
メタデータ更新用の JSON ファイルを作成します。uris
の値は上記で確認したものを使用し、gcs
を gs
に修正してください。
bq mkdef --source_format=ICEBERG \
"gs://manabianqiita/snowflake/customer_iceberg/metadata/00002-d56a73ad-6788-4b8e-bbd1-494f3db9913d.metadata.json" > biglake_version
作成した JSON 定義ファイルを元に、以下のコマンドでテーブルのメタデータを更新します。{project_id}
の部分はご自分のプロジェクト ID に置き換えてください。
bq update --autodetect_schema --external_table_definition=biglake_version \
{project_id}:test.customer_iceberg
更新後、BigQuery から最新のデータを取得できることを確認します。
SELECT * FROM test.customer_iceberg;
本記事では bq コマンドを使用していますが、運用時には Snowflake から取得したメタデータファイルのパスを、REST API で更新するプログラムを実装することをおすすめします。
出所:https://cloud.google.com/bigquery/docs/iceberg-external-tables?hl=ja#api