水曜日, 7月 2, 2025
水曜日, 7月 2, 2025
- Advertisment -
ホームニューステックニュース複数の dbt プロジェクトに対応! dbt-docs を Snowflake で効率的にホスティングする方法(SiS vs SPCS)

複数の dbt プロジェクトに対応! dbt-docs を Snowflake で効率的にホスティングする方法(SiS vs SPCS)


はじめまして、株式会社ナウキャストでデータエンジニアをしている高橋です。弊社では、Snowflakeのデータ変換ツールとして、dbt-coreを利用しています。dbt-coreはオープンソースで無料にもかかわらず、データ変換やモデリング、テスト、ドキュメント生成など、データ基盤の運用に役立つ多くの機能が揃っており、とても便利なツールです。2025年6月時点では、dbt project on Snowflakeの機能がPuPrされており、Snowflake上でdbtの開発・運用ができるようになることが想定されます。

しかし、dbt-coreは無料で便利な反面、dbt Cloudのような統合管理機能はありません。そのため、プロジェクト数が増えてくると、それぞれのdbt projectごとにdbtドキュメントが生成され、管理や閲覧が煩雑になってしまいます。各プロジェクトで個別に生成されたdbtドキュメントを一つ一つ見に行くのは、思った以上に手間がかかります。

そこで、このdbtドキュメントをSnowflake内で管理し、ユーザーが一つのページから複数のdbtドキュメントを簡単に閲覧できるアプリを構築してみました。

今回は、Snowflake内でdbtドキュメントを公開する方法として、「Streamlit in Snowflake(SiS)」と「Snowpark Container Service(SPCS)」の2種類のアプローチでアプリを構築し、それぞれの特徴や使い勝手を比較してみました。

今回構築したコードは以下で公開しています。本稿では詳細なアプリケーションの構築方法については割愛させていただきます。(SPCSのインフラ構築については後述で簡単に紹介しています)

https://github.com/t-hiroto/streamlit-dbt-docs

Snowflakeインフラの準備(SPCS)

1. SPCS(Compute Pool, Image Repository, Stage)の作成


create compute pool if not exists dbt_docs_pool
    min_nodes = 1
    max_nodes = 1
    instance_family = CPU_X64_XS
    auto_suspend_secs = 300
    auto_resume = true
    comment = 'dbt-docs application用のコンピュートプール'
;


create image repository if not exists dbt_docs_repository
    comment = 'dbt-docs application用のイメージリポジトリ'
;


create stage if not exists dbt_docs_stage
    directory = ( enable = true )
    comment = 'dbt-docs application用のステージ'
;

2. イメージのプッシュ

Streamlitアプリケーションのデプロイ時に必要になるため、以下のクエリ実行結果のrepository urlを確認します

-- repository urlの確認
show image repositories;

repository urlを確認することができたら、spec.yamlを修正します
今回は、Streamlitの実行ユーザーの認証方法位にはPATを採用しています

https://docs.snowflake.com/en/user-guide/programmatic-access-tokens

spec:
  containers:
    - name: >
      image: />:>
      env:
        SERVER_PORT: 8501
        SNOWFLAKE_ROLE: >
        SNOWFLAKE_WAREHOUSE: >
      readinessProbe:
        port: 8501
      secrets:
        - snowflakeSecret: >.>.>
          secretKeyRef: PASSWORD
          envVarName: SNOWFLAKE_PASSWORD
        - snowflakeSecret: >.>.>
          secretKeyRef: USERNAME
          envVarName: SNOWFLAKE_USER
  endpoints:
    - name: >
      port: 8501
      public: true
  networkPolicyConfig:
    allowInternetEgress: true

spec.yamlの修正が完了したら、アプリケーションのdocker imageをpushします。

snow stage copy spec.yaml @dbt_docs_stage --overwrite
docker build . -t repository url>:tag> --no-cache --platform linux/amd64
snow spcs image-registry login
docker push repository url>:tag>

3. サービスの作成

image repositoryの更新が完了したら以下のクエリを実行し、SERVICEを作成します。


create service dbt_docs_application_service
    in compute pool dbt_docs_pool
    from @dbt_docs_stage
    specification_file = 'spec.yaml'
    min_instances = 1
    max_instances = 1
;

以下のクエリ実行結果のingress_urlからStreamlitアプリケーションにアクセスすることができます。

-- サービスエンドポイントの確認
show endpoints in service dbt_docs_application_service;

4. dbtドキュメントの更新

dbtドキュメントの保管場所はSnowflakeの内部ステージに保管することを想定しています。dbtプロジェクトの変更時にCICD経由でHTMLファイルを更新し常に最新のdbtドキュメントを取得できることを想定しました。

以下のコマンドでdbtドキュメントの生成および更新を実行することができます

dbt docs generate --static
snow stage copy source_path> destination_path> --overwrite

5. streamlitアプリのデプロイ

SiSのデプロイには以下のコマンドを実行します

uv run snow streamlit deploy --replace

SPCSのデプロイには以下のコマンドを実行します

docker push repository url>:tag>
snow spcs service upgrade SERVICE_NAME> --spec-path spec.yaml

内部ステージの中身に以下のオブジェクトが格納されていれば、エンドポイントから
streamlitアプリの画面を参照することができるはずです。

@DBT_DOCS_STAGE
├─ statics
│  ├─ dbt-docs-A.html
│  ├─ dbt-docs-B.html
│  └─ dbt-docs-C.html
├─ dbt_docs
│  ├─ statics
│  │  └─ .gitkeep
│  ├─ .streamlit
│  │  └─ config.toml
│  ├─ common
│  │  └─ snowflake_connection.py
│  ├─ streamlit_app.py
│  └─ envrionment.yml
└─ spec.yaml


SiSで表示される画面


SPCSで表示される画面

Streamlitアプリケーションの詳細

dbtドキュメントの読み込み

Streamlitアプリケーションからdbtドキュメントの読み込みは以下の部分で行なっています。Snowpark Python APIを使って内部ステージに対して、LISTクエリおよびGETコマンドを実行し、HTMLファイルを取得します。

https://github.com/t-hiroto/streamlit-dbt-docs/blob/fa427daeb377f757dbb56f3a86ea32a4a259964b/apps/dbt-docs/streamlit_app.py#L64-L86

snowflake.snowpark.Sessionの取得

今回の構成の場合、Streamlitアプリケーションは実行環境ごとにsnowflake.snowpark.Sessionの取得方法が異なるため、以下のようにlocal, streamlit, spcsそれぞれの取得メソッドを作成しました。

https://github.com/t-hiroto/streamlit-dbt-docs/blob/f905ca57e2ff2b88ba22da261f574ca16cdcb1af/apps/dbt-docs/common/snowflake_connection.py#L12-L87

消費クレジットの比較

SPCSにかかるコスト

SPCSのコストは以下のカテゴリに分類されます:

  • コンピューティングプールコスト:

    • 仮想マシン (VM) ノードの集合体にかかる費用。
    • ノードの数とタイプ (インスタンスファミリー) によって消費クレジットが決定。
    • IDLE (アイドル状態) でも課金が発生するが、AUTO_SUSPEND 機能で最適化可能。
    • コンピューティングプールインスタンスファミリーごとのクレジット消費量
      • CPUインスタンスタイプ: CPU_X64_XS (0.06クレジット/時) から CPU_X64_L (0.83クレジット/時)。
      • 高メモリインスタンスタイプ: HIGHMEM_X64_S (0.28クレジット/時) から HIGHMEM_X64_L (4.44クレジット/時)。
      • GPUインスタンスタイプ: GPU_NV_XS (0.25クレジット/時) から GPU_NV_SL (13.50クレジット/時)。
  • ストレージコスト:

    • イメージリポジトリ、ログストレージ、ボリュームマウント、ブロックストレージなど。
  • データ転送コスト:

    • 外部へのデータ移動 (アウトバウンド) や内部データ転送にかかる費用。
  • ブロックストレージ料金:

    • 例: AWS US East (Northern Virginia) では81.92 USD/TB/月。
  • データ転送料金:

    • 例: AWS US East (Northern Virginia) からインターネットへのデータ転送は90.00 USD/TB。

SiSにかかるコスト

Streamlitのコストは主に以下に依存します:

  • 仮想ウェアハウスのコンピューティングコスト:

    • アプリの実行やSQLクエリに必要なウェアハウスの利用。
    • WebSocket接続がアクティブな間は課金が継続。
    • AUTO_SUSPEND やウェブページを閉じることでアイドルコストを削減可能
    • streamlitSleepTimeoutMinutesの設定
  • 仮想ウェアハウスのクレジット消費量:

    • Standard Warehouse: XS (1クレジット/時) から L (8クレジット/時)。
    • Gen 2 Warehouse: XS (1.35クレジット/時)。
    • Snowpark Optimized Warehouses: XS (1.00クレジット/時)。

コンピューティングコストの比較

項目 SPCS Streamlit in Snowflake
最小単位のコスト 最小インスタンス (CPU_X64_XS): 0.06クレジット/時 最小ウェアハウス (XS): 1クレジット/時 (Standard Warehouse)
高性能オプション GPUや高メモリインスタンスは高価 (GPU_NV_SL: 13.50クレジット/時) 高性能オプションはなし
最低課金時間 5分 1分
アイドルコスト IDLE状態でも課金されるが、AUTO_SUSPEND で最適化可能 WebSocket接続が切れるまでデフォルトで約15分間課金が続く(手動で接続を切ることは可能)

ストレージコストの比較

項目 SPCS Streamlit in Snowflake
基本ストレージコスト Snowflakeステージを利用するため共通 Snowflakeステージを利用するため共通
追加ストレージコスト コンテナイメージやブロックストレージの追加コストが発生 なし

データ転送コストの比較

項目 SPCS Streamlit in Snowflake
外部データ転送 両者とも外部へのデータ転送には料金が発生 両者とも外部へのデータ転送には料金が発生
内部データ転送 コンピューティングプール間やウェアハウス間の内部データ転送にコストが発生する場合あり 内部データ転送のコストは通常意識されない

今回の構成における料金シミュレーション

  • 条件
    • dbtユーザーがdocsを閲覧する時間:5分/回
      • 1日6回時間帯の重複なく閲覧される
    • 1ヶ月30日で計算する
  • SPCS
    • アプリ起動時間 = 5分/回 × 6回/日 = 30分/日
    • アイドル時間 = 5分/回(1回の稼働ごとに最大5分のアイドル時間が発生) × 6回/日 = 30分/日
    • 合計稼働時間 = 30分/日(アプリ起動時間)+ 30分/日(アイドル時間)= 60分/日(30時間)
    • 消費クレジット = 30時間 × 0.06クレジット/時 = 1.8クレジット。
  • SiS
    • アプリ起動時間 = 5分/回 × 6回/日 = 30分/日
    • アイドル時間 = 5分/回(1回の稼働ごとに最大5分のアイドル時間が発生) × 6回/日 = 30分/日
    • 合計稼働時間 = 30分/日(アプリ起動時間)+ 30分/日(アイドル時間)= 60分/日(30時間)
    • 消費クレジット = 30時間 × 1クレジット/時 = 30クレジット
項目 SPCS (CPU_X64_XS) SiS (X-Small)
アプリ起動時間 30分/日 30分/日
アイドル時間 30分/日 30分/日
1か月の合計稼働時間 30時間 30時間
消費クレジット 1.8クレジット 30クレジット

実際に消費されたクレジットを確認するには以下のクエリを実行し確認することができます

select
    start_time,
    end_time,
    datadiff (second, start_time, end_time) as duration,
    credits_used
from
    snowflake.account_usage.snowpark_container_service_history
where
    compute_pool_name = your_compute_pool_name>
order by start_time desc
;

使い分けの考え方

SPCSが最適となるケース

  • カスタムアプリケーションのホスティング: WebサービスやAPIを長時間稼働させる場合。
  • GPUを必要とするML/AIワークロード: 高度な計算処理を行う場合。
  • 多様な言語やライブラリの利用: Python以外の言語や特定のライブラリを必要とする場合。
  • バッチ処理や非同期ジョブ: 必要な時だけ起動するジョブを実行する場合。

Streamlit in Snowflakeが最適となるケース

  • インタラクティブなダッシュボード/データアプリケーション: データ分析者が迅速に構築・共有したい場合。
  • 開発の容易性と迅速なフィードバック: 開発効率を重視する場合。
  • 小規模なワークロード: 小規模なウェアハウスで十分な場合。

複数のdbt ドキュメントの参照アプリ

今回のように、SiSとSPCSを採用することで、S3などにHTMLファイルを管理し、ホスティング+ユーザー認証を行うシステムをSnowflake外で構築しなくていいのは嬉しいポイントです。

簡単にプロジェクトを横断したdbt ドキュメントのアプリケーションを構築したい場合はご参考にしていただければと思います。

複数のdbt projectのドキュメントアプリについては、dbt project on Snowflakedbt-loomなど様々なサービスがもあるので、いつかプロジェクトを横断したdbt ドキュメントの参照の悩みは解決されるかもしれないので、引き続きチェックしていきたいです。

SiS vs SPCSについて

SPCS は、高性能なカスタムコンテナアプリケーションやGPUを必要とするML/AIワークロードに適しており、適切なインスタンス選択と運用最適化で高いコスト効率を発揮します。一方、Streamlit in Snowflake は、インタラクティブなダッシュボードやデータアプリケーションを迅速に構築・展開するのに優れていますが、大規模なデータ処理やアイドル時間の課金には注意が必要になりそうです。

個人的には、SPCSについてTerraformの対応やSnowflake CLIの機能が充実してきているため、構築作業は以前に比べて楽になってきていると思います。料金コストについてもWarehouseの稼働単価よりCompute Poolの稼働単価の方が安価になりそうです。(ただ、Webページを閉じないとauto_suspendされないので、実際利用してみるとシミュレーション通りにはいかないかもしれません)

SiSの方はやはり簡単に構築ができるため、インタラクティブなアプリ開発には向いていると思います。この長所・短所を念頭に選択して行けたらいいと思いました。

Snowflake上でデータアプリを開発するときの参考にしていただけたら幸いです。



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -