0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Databricksで作成したデータをSnowflakeから読み書きする。

0
Posted at

今日のゴール

  • DatabricksのUnityCatalogのデータをSnowflakeから読み込む。
  • SnowflakeからDatabricksへTable単位で書き込む。
  • DatabricksにdbtからTable作成し、Snowflakeから読み込む。

image.png

用意するもの

  • AWS (ご自分の環境)
    • IAM
      • policy
      • Role
    • S3
  • Databricks (Free Edition)
  • Snowflake (Trial / AWS Enterprise Edition / Oregon)
  • dbt (free account or dbtCore)

DataBricks の作業内容

  • S3 を使用する外部ロケーションを作成
  • Iceberg 読み取りを有効にする Delta テーブルを作成
  • OAuth シークレットを作成
  • メタストアでの外部データ アクセスを有効にする

Snowflake の作業内容

  • カタログ統合を作成
  • 外部ボリュームを作成
  • カタログリンクデータベースを作成

AWS 詳細

AWS S3

  • bucketを1つ作成しておく(eg. "databricks-snowflake-bucket")
  • AWSのリージョン注意(Snowflakeの設定参照)

AWS IAM Policy

作成したS3 bucketに読み書きできる権限をRoleにつければOK

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": [
                "arn:aws:s3:::<s3-bucket-name>/*",
                "arn:aws:s3:::<s3-bucket-name>"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::999999999999:role/<aws-role-name>"
            ],
            "Effect": "Allow"
        }
    ]
}

AWS IAM Role

  • 作成したpolicyをDatabricksとSnowflakeが利用しているAWS環境と信頼関係を結ぶ。
    ( "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL" はDatabricksの固定のようです。)
    あとからDatabricksとSnowflakeの設定してから更新する。
  • 作成したRoleのARNを控えておいてください。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
          "arn:aws:iam::<YOUR-AWS-ACCOUNT-ID>:role/<THIS-ROLE-NAME>"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<STORAGE-CREDENTIAL-EXTERNAL-ID>"
        }
      }
    }
  ]
}

Databricks 作業詳細

とりあえずUIを日本語化
  • 右上のアイコン(名前のアルファベット) -> Settings(設定) -> Preferences(環境設定) -> Language(言語) -> 日本語
資格情報を作成
  • 新規資格情報を作成(Create a credential)

  • カタログ -> + -> 資格情報を作成
    image.png

  • 新規資格情報を作成画面で入力し、作成ボタンを押す。

    • ストレージ資格情報
    • 資格情報のタイプ:AWS IAMロール
      • インスタンスプロファイルからコピー
    • 資格情報名:<お好きな名前でどうぞ>
    • IAMロール(ARN):<ご自分のAWS環境で作成したRoleのARN>
      image.png
  • 「資格情報が作成されました」の画面から、「外部ID」を控えておく。
    image.png

  • AWS Roleを更新する。

    • 外部IDを"sts:ExternalId"に書き換える(「資格情報が作成されました」画面の信頼ポリシー参照)
  • 右上の「構成を検証」ボタンを押すと接続のテスト結果が出るので確認する。
    (引っかかりそうなところは、AWS Role、資格情報の作成)
    image.png

S3 を使用する外部ロケーションを作成
  • カタログ -> + -> 外部ロケーションを作成

  • 新しい外部ロケーションを作成 -> 手動 を選択 -> 次のページ
    image.png

  • 新しい外部ロケーションを手動で作成

    • 外部ロケーション名:<お好きな名前>
    • ストレージタイプ:S3
    • URL: <>
    • ストレージ資格情報:<作成した資格情報>
    • コメント:<お好きに>
新規カタログを作成
    • -> カタログを作成から、以下の内容で作成。
    • カタログ名:<お好きに>
    • タイプ:Standard
    • ストレージの場所:<作成した外部ロケーション>
    • サブ/パス:<お好きに>

image.png

Iceberg 読み取りを有効にする Delta テーブルを作成
  • スキーマ、テーブルの作成
    • SQLエディタとかNotebookとか、なんでもいいです。テーブル作成してデータ投入したら、SELECT等で確認しましょう。テーブル作成時に指定したS3のパスにファイルがあることも確認しましょう。
    • Delta Lake に格納されたテーブルで Iceberg 読み取りを有効にします。
    • Iceberg 形式で使える型はサービスによって異なるので、互換性は注意した方がいいです。
CREATE SCHEMA IF NOT EXISTS DBX_SNOW_CATALOG.ICE_SCHEMA;

USE CATALOG DBX_SNOW_CATALOG;
USE SCHEMA ICE_SCHEMA;


create TABLE dbx_table_01(c1 INT) 
USING DELTA
LOCATION 's3://<s3-bucket>/dbx_snow_cat/ice_schema/dbx_table_01/'
TBLPROPERTIES(

'delta.columnMapping.mode' = 'name',
'delta.enableIcebergCompatV2' = 'true',
'delta.universalFormat.enabledFormats' = 'iceberg'

);

insert into dbx_table_01 values (1),(2),(3),(4),(5);

select * from dbx_snow_catalog.ice_schema.dbx_table_01;

OAuth シークレットを作成
  • 右上のイニシャルアルファベットアイコンから、設定 -> ワークスペース管理者 -> IDとアクセス -> サービスプリンシパル -> 管理へいきます。

image.png

  • 「Service Pricipalを追加」を押します。

  • サービスプリンシパル名:<お好きな名前>
    で「追加」します。
    image.png

  • 一覧に表示された中から詳細画面へ行き、「シークレットを作成」します。
    image.png

  • 存続期間(日)を入力し、「生成」します。
    image.png

  • シークレット、クライアントIDを控えます。
    image.png

  • 設定タブに移動し、アプリケーションIDを控えます。

サービスプリンシパルに権限設定する
  • Snowflakeからの読み書きができるように、Grantつけます。今回はお試し環境なので強権限つけてますが、本番環境へは考慮が必要です。
-- 読み込み用
GRANT USE CATALOG ON CATALOG dbx_snow_catalog  TO `<アプリケーションID>`;
GRANT USE SCHEMA  ON SCHEMA dbx_snow_catalog.ice_schema TO `<アプリケーションID>`;
GRANT SELECT ON TABLE dbx_snow_catalog.ice_schema.dbx_table_01 TO `<アプリケーションID>`;

-- 書き込み用
grant all privileges on schema dbx_snow_catalog.ice_schema to `<アプリケーションID>`;
grant external use schema on catalog dbx_snow_catalog to `<アプリケーションID>`;
grant all privileges on catalog dbx_snow_catalog to `<アプリケーションID>`;

メタストアでの外部データ アクセスを有効にする
  • このあとSnowflakeから ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS で接続するために、Databricksの該当リージョンのメタストアの外部データアクセスを有効にしておく必要があります。(この設定はリージョン毎に1つなので、共有環境の場合は管理者と相談する必要があります)
  • カタログ -> 歯車⚙ -> メタストア

image.png

  • 外部データアクセスを「有効」にします。
    image.png

Snowflake の作業詳細

カタログ統合を作成
  • Iceberg REST カタログ統合を作成します。
CREATE OR REPLACE CATALOG INTEGRATION unity_catalog_int_oauth
  CATALOG_SOURCE = ICEBERG_REST
  TABLE_FORMAT = ICEBERG
  CATALOG_NAMESPACE = 'dbx_snow_catalog' // Snowflakeで使うカタログ名(Databricksのカタログ名)
  REST_CONFIG = (
    CATALOG_URI = 'https://xxxx.cloud.databricks.com/api/2.1/unity-catalog/iceberg-rest'   // DatabricksのワークスペースのURL参照
    CATALOG_NAME = 'dbx_snow_catalog'// Databricksのカタログ名
    ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS
  )
  REST_AUTHENTICATION = (
    TYPE = OAUTH
    OAUTH_TOKEN_URI = 'https://xxxx.cloud.databricks.com/oidc/v1/token'  // DatabricksのワークスペースのURL参照
    OAUTH_CLIENT_ID = '<クライアントID>'//'<client-id>'
    OAUTH_CLIENT_SECRET = '<シークレット>'//'<secret>'
    OAUTH_ALLOWED_SCOPES = ('all-apis', 'sql')
  )
  ENABLED = TRUE
  REFRESH_INTERVAL_SECONDS = 30
;


  • 確認します。"success":true"になっていればOKです。(エラーの場合は、各所見直しです。。)
SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('unity_catalog_int_oauth');

外部ボリュームを作成
  • S3との連携用に外部ボリューム作成します。
CREATE OR REPLACE EXTERNAL VOLUME s3_dbx_ext_snow_vol
  STORAGE_LOCATIONS =
    (
      (
        NAME = 's3_dbx_ext_snow_vol'
        STORAGE_PROVIDER = 'S3'
        STORAGE_BASE_URL = 's3://<your-s3-bucket>/'
        STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::<your-aws-role-arn>'
        ENCRYPTION=(TYPE='AWS_SSE_S3')
      )
    )
  ALLOW_WRITES = TRUE;
  • 成功したら、以下のSQLでSnowflakeのAWS情報を取り出します(property_valueのjsonに入っています
DESC EXTERNAL VOLUME s3_dbx_ext_snow_vol;

image.png

  • ご自分のAWS環境のRoleに、上記のJSONの"STORAGE_AWS_IAM_USER_ARN"、"STORAGE_AWS_EXTERNAL_ID"の情報を追記して更新します。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
          "arn:aws:iam::<YOUR-AWS-ACCOUNT-ID>:role/<THIS-ROLE-NAME>",
          "arn:aws:iam::<"STORAGE_AWS_IAM_USER_ARN">"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<STORAGE-CREDENTIAL-EXTERNAL-ID>",
          "<"STORAGE_AWS_EXTERNAL_ID">"
        }
      }
    }
  ]
}
  • Role更新後、以下のSQLで"success":true" が返ってくればOKです。
SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('s3_dbx_ext_snow_vol');
カタログリンクデータベースを作成
  • 以下のコマンドでデータベースを作成し、成功すると、リンクマークのついたデータベース、Databricksで作成したスキーマ、テーブルがSnowflake上に表示されます。
CREATE DATABASE dbx_cat_db
  LINKED_CATALOG = (
    CATALOG = 'unity_catalog_int_oauth',
    SYNC_INTERVAL_SECONDS = 30
  )
  EXTERNAL_VOLUME = 's3_dbx_ext_snow_vol';

image.png

Databricksで作成したデータの内容を、Snowflakeから確認する。
  • SELECTしてデータが表示されればOK
select * from dbx_cat_db."ice_schema"."dbx_table_01";
Snowflakeからテーブルを作成し、データを挿入する。
create or replace ICEBERG TABLE dbx_table_02  (id int)
  AUTO_REFRESH = TRUE;
;
insert into dbx_table_02 values (100);
insert into dbx_table_02 values (200);
  • Databricksからテーブルが表示されていて、データが確認できればOK
    image.png

image.png

dbt モデル設定

  • Databricsでモデル作成時に、configに以下のように設定を入れると、Iceberg読み取り形式でTable作成することができる。(DatabricksでのTable作成時の設定+α)
{{  config(    
  tblproperties = {       
  'delta.columnMapping.mode':'name',       
  'delta.enableDeletionVectors': 'false',
  'delta.enableIcebergCompatV2':'true',
  'delta.universalFormat.enabledFormats':'iceberg'  
})}}

Select * from hoge

SnowVillage Unconference #8 で発表したときの話

  • ざっくりした資料を作って、わいわいディスカッションしてきました。
    • Snowflakeからの自動更新時に使われるコンピュートはサーバレスなので、1分課金ではない。
    • Icebergはバージョンによってできることがちがう。(勉強が必要だ・・)

参考サイト(ありがとうございます!)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?