01 ソース環境
実際の顧客デプロイを反映した Snowflake 環境をプロビジョニングします — 5,000万行、dbt Medallion パイプライン、稼働中の trip プロデューサー、3つの Superset ダッシュボード。
開始チェックポイント
モジュール00が完了していること。ツールチェーンがインストールされ、両方のクラウドのトライアル
アカウントが有効で、リポジトリがクローンされ、dbt-snowflake の仮想環境が構築されていること。
このモジュールは約45分かかり、およそ2〜4 Snowflake クレジットを消費します。
なぜ必要か
おもちゃのソースを相手にマイグレーションを計画することはできません。数行しかないフラットな
テーブル1つでは、実際のマイグレーションを難しくしているあらゆる判断を回避できてしまいます。この
モジュールでは、その代わりに実際の顧客デプロイの形を作ります。半構造化 JSON を保持する
VARIANT カラム、CDC ストリーム、スケジュールされたタスク、増分の MERGE パイプライン、そして
それらすべての上で読み取りを行う BI レイヤーです。これらのすべてが、モジュール02では具体的な
マイグレーションの判断になります。このモジュールは、その判断が出てきたときに抽象論ではなく
実物を指し示せるようにするために存在します。
概念 — 内部の仕組み
インフラ(Terraform)。 setup.sh を実行すると、次がプロビジョニングされます。
- ウェアハウス —
TRANSFORM_WH(SMALL、ELT 用)とANALYTICS_WH(MEDIUM、BI 用)、 それに月50クレジットで上限を設けたリソースモニター(ANALYTICS_WH_MONITOR)。 - データベース —
NYC_TAXI_DB、3つのスキーマ(RAW、STAGING、ANALYTICS)を持ちます。 - ロール —
TRANSFORMER_ROLE、ANALYST_ROLE、DBT_ROLE、LOADER_ROLE。
Medallion の形。 データは NYC_TAXI_DB の中を3つのレイヤーを通って進みます。
- RAW —
TRIPS_RAW(5,000万行の合成 trip 行。アプリのテレメトリを模したTRIP_METADATAVARIANTカラムを含みます — これが JSON のマイグレーション課題です)と、ディメンション テーブル(DIM_TAXI_ZONES、DIM_PAYMENT_TYPE、DIM_VENDOR)。 - STAGING — 型を整え、
VARIANTカラムをフラット化する dbt の view。 - ANALYTICS — dbt のテーブルと増分モデル:
fact_trips(5,000万行、MERGE戦略)、 4つのディメンションテーブル、そしてagg_hourly_zone_trips(増分の集計)。
このパイプラインを dbt とは独立に自走させている Snowflake のオブジェクトが2つあります。
TRIPS_CDC_STREAM—TRIPS_RAW上の Change Data Capture ストリーム。CDC_CONSUME_TASK— そのストリームを5分ごとに読み取ります(RAWで動作し、セットアップ中に resume されます)。そしてHOURLY_AGG_TASKは、時間別集計を1時間ごとにリフレッシュします (STAGINGで動作し、dbt のビルド後に resume されます)。
Superset。 3つのダッシュボードはすべて ANALYTICS_WH を通じて ANALYTICS スキーマから
読み取ります。どれも RAW や STAGING に直接触れません。この読み取り経路が、ワークショップの
後半で ClickHouse 側に再現するものです。
手順1 — 認証情報を設定する
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
cp .env.example .env
# Edit .env with your Snowflake credentials
cp dbt/nyc_taxi_dbt/profiles.yml.example ~/.dbt/profiles.yml
# Edit ~/.dbt/profiles.yml with your account details.env と ~/.dbt/profiles.yml はどちらも gitignore されています。Snowflake のアカウント、
ユーザー、パスワードを保持するファイルです。どちらも決してコミットしないでください。
手順2 — セットアップを実行する
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
source .env && ./setup.shこれには 5〜10分 かかります。その大半は TABLE(GENERATOR) で5,000万行の合成 trip データを
生成する時間です。setup.sh は Terraform のインフラをプロビジョニングし、TRIPS_RAW に
シードを投入し、dbt のビルドを実行し、Docker Compose(trip プロデューサーと Superset)を
一気に立ち上げます。
手順3 — プロデューサーと Superset を起動する
setup.sh は正しい環境で Docker Compose を立ち上げ、Superset に Snowflake 接続を登録し、
3つのダッシュボードすべてを自動的にインポートします。
superset/dashboards/ にコミットされているダッシュボードの ZIP は、sqlalchemy_uri が
プレースホルダー(LAB_USER、MYORG-MYACCOUNT)に置き換えられています。自動インポートは
あなたの .env から URI を再設定するので、setup.sh を実行する場合はこれが透過的に処理されます。
代わりに Superset の UI から ZIP を手動でインポートすると、作成される接続はそれらの
プレースホルダーを使うため接続できません。その場合は、あとから接続を編集して実際の Snowflake
アカウントを指すようにしてください。
Superset を手動で再起動する必要がある場合は次のようにします。
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake/superset"
docker-compose --env-file ../.env up -d--env-file ../.env フラグは、親ディレクトリから環境変数を読み込みます。
3つのダッシュボードは Operations Command Center、Executive Weekly Report、Driver & Quality Analytics です(最後のものは意図的に遅くしてあります。ワークショップ後半での ClickHouse ベンチマークのターゲットです)。データソース、チャート、フィルターを含むダッシュボードの 完全な構築については、 Superset on Snowflake を参照してください。
手順4 — dbt を最新に保つ
trip プロデューサーは TRIPS_RAW に毎分約60件の trip を継続的に挿入します。作業中も
fact_trips と agg_hourly_zone_trips を最新に保つため、別のターミナルで dbt のリフレッシュ
ループを実行してください。
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
# Default: refresh every 5 minutes (auto-sources .env)
./scripts/run_dbt.sh
# Custom interval
./scripts/run_dbt.sh --interval 15m
# Run once and exit
./scripts/run_dbt.sh --once
# Include dbt tests after each run
./scripts/run_dbt.sh --test| フラグ | 効果 |
|---|---|
--interval <n> | 実行間隔: 30s、5m、1h、または秒数のみ(デフォルト: 5m) |
--once | リフレッシュを1回だけ実行して終了する |
--test | 各 dbt run の後に dbt test を実行する |
このスクリプトは常に 増分で 実行されます。--full-refresh は決して行わないため、
プロデューサーが挿入した行は保持されます。停止したいときはいつでも Ctrl-C を押してください。
ラボの残りの間は専用のターミナルで動かし続けてください。モジュール03でもこれに依存しています。
手順5 — クエリライブラリを見てみる
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"クエリのディレクトリ(workshop_public/snowflake_migration_lab/01-setup-snowflake/queries/)には、
注釈付きの SQL ファイルが7本入っています。どれもいま構築した Snowflake 環境に対して実行できます。
そしてそれぞれに、モジュール02で ClickHouse へ変換することになる、意図的なマイグレーション課題が
仕込まれています。
| クエリ | 構文 | マイグレーション課題 |
|---|---|---|
| Q1 | DATE_TRUNC、DATEADD | 構文の細かな差異 |
| Q2 | ウィンドウ関数の ROWS BETWEEN | ClickHouse でもほぼ同一 |
| Q3 | QUALIFY | ClickHouse では v24.5 以降ネイティブ対応 — ここでは移植性のためサブクエリに書き換える |
| Q4 | LATERAL FLATTEN | 対応物なし — JSONExtract を使う、または事前にフラット化する |
| Q5 | VARIANT のコロンパス | JSONExtractFloat/JSONExtractString に置き換える |
| Q6 | MERGE INTO | 対応物なし — ReplacingMergeTree を使う |
| Q7 | Snowflake Streams | カットオーバー時に廃止 — ライブ書き込みはプロデューサー経由で直接 ClickHouse へ |
次に進む前に、各ファイルを開いて自分の Snowflake 環境に対して実行してください。各クエリの コメントブロックには ClickHouse での対応方法の下書きがすでに書かれています。その側を実際に書いて 実行するのはモジュール02です。
完了の確認方法
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
source .env && ./scripts/verify_environment.shこれは次の点を確認します。
- データベースとスキーマ —
NYC_TAXI_DBが存在し、RAW、STAGING、ANALYTICSがある。 - テーブルとデータ —
TRIPS_RAWに約5,000万行あり、FACT_TRIPSにデータが入っており、 ディメンションが存在する。 - CDC ストリーム —
TRIPS_RAW上にTRIPS_CDC_STREAMが存在する。 - スケジュールされたタスク —
CDC_CONSUME_TASKとHOURLY_AGG_TASKがstarted状態にある。 - CDC の稼働 — タスクが最近実行されている。
- プロデューサーの供給 — trip プロデューサーが継続的にデータを挿入している。
- Superset — BI ダッシュボードに
http://localhost:8088でアクセスできる。
手作業で確認したい場合は、ACCOUNTADMIN ロールで
SHOW TASKS LIKE '%TASK' IN DATABASE NYC_TAXI_DB; を実行すると(タスクはそのロールが所有しています)、
両方のタスクが動いていることを確認できます。
まとめ
この環境には、これから数モジュールにわたって繰り返し戻ってきます。そして ./setup.sh のフル実行は
5〜10分かかるので、Terraform ファイルや dbt モデルを少し直すたびに毎回その時間を払いたくは
ありません。setup.sh にはまさにそのためのフラグがあります。
| フラグ | 使う場面 |
|---|---|
| (なし) | 初回実行。すべてをプロビジョニングし、5,000万行の合成データを生成する(合計約12分)。 |
--skip-seed | インフラがすでに存在し、TRIPS_RAW にすでにデータがある場合。合成データ生成をスキップする(約8分の節約)。 |
--skip-dbt | Snowflake のオブジェクトは存在するが、dbt の変換を再実行する必要がない場合(例: Terraform の変更をテストするとき)。 |
--skip-superset | Docker が動いていない、またはまだ BI レイヤーが必要ない場合。 |
--full-refresh | すべての増分モデルをゼロから再構築するよう dbt に強制する(例: スキーマ変更のあと)。 |
フラグは組み合わせられます。よく使う組み合わせは2つです。
# Re-run after a Terraform or SQL change — skip the ~10 min data load
./setup.sh --skip-seed
# Iterate on dbt models only — skip everything else
./setup.sh --skip-seed --skip-supersetコストに関する注記。 データのシード投入は約12分で2クレジット(約$6)、dbt のフルビルドは 約8分で1.5クレジット(約$5)です。8時間のパートナーラボセッションではさらに約12クレジット (約$36)加算されます。ウェアハウスはアイドル時に自動サスペンドするので、セッションの合間に コストは積み上がりません。パートナー1人あたり1日の合計はおよそ16クレジット、約$47です。
終了状態
Snowflake が稼働しています。NYC_TAXI_DB は完全に構築され、CDC ストリームと2つのスケジュール
タスクが動作し、trip プロデューサーが TRIPS_RAW に毎分約60件の trip を書き込み、3つの
Superset ダッシュボードすべてが http://localhost:8088 で立ち上がっています。
プロデューサーは動かし続けてください。 Docker Compose のスタックを停止してはいけません。また
./teardown.sh を実行してもいけません。モジュール02から05はこの環境が稼働し続けていることに
依存しており、モジュール05のカットオーバー手順では、マイグレーション中にプロデューサーが
Snowflake と ClickHouse の間に作るギャップを正確に測定します。いま撤去すると、この手順まで
原因を追いにくい形でワークショップの残りが失敗します。撤去はここではなく、モジュール05の最後で
扱います。