メインコンテンツへスキップ
見出し画像

Dagster 移行、500テーブル超を止めずに引っ越した話

    こんにちは!Scene Live bq事業本部のまっすーです。

    2025年からデータサイエンティスト兼データエンジニアとして、Scene Liveに中途入社しました。bqというサービスのLLMを用いた検証・研究をおこなったり、プロダクトに関するデータ収集から利活用までの『データ基盤』を作ったりしています。

    連載:「モダンデータスタック続編」第 2 回 / 全 3 回
    ▼第 1 回

    既刊:【1ヶ月半で構築】bq事業のモダンデータスタック


    はじめに

    前回(第 1 回)は、Airflow から Dagster に乗り換えた 「なぜ」 を書きました。今回はその続きで 「どうやって」 の話です。

    具体的には、 500 テーブル超 の本番データ基盤を、ユーザー(社内ビジネスサイド・チームメンバー)に気づかれないように Dagster へ引っ越した、その段取りの話。
    正直なところ、引っ越しはきれいにはいきませんでした。3 日ほどデータの更新を止めたこともあったし、想定外のことも色々起きました。今回はその正直な話を、再現できる形で書き残しておきます。


    この記事の前提(用語の整理)

    第 1 回で出てきた用語(Cloud Composer / CRJ / CRS / BigQuery / Airflow / Dagster / Asset / Pipes)は引き続き使います。本記事で新しく登場する用語は以下です。


    • dbt(data build tool): SQL でデータ加工を記述する OSS。SELECT 文を書くと「テーブルを作る」「ビューを作る」を dbt が面倒みてくれる。GitHub での開発プロセスにも乗せやすい。第 1 回でも触れましたが、本記事では話の主役の一つになるので再掲

    • dlt(data load tool): Python で「外部からデータを取り込む」処理を書く OSS。dbt と似た開発体験で取り込みパイプラインが書ける。第 1 回でも軽く触れた通り、Dagster 移行と同時に導入した

    • dbt snapshot: dbt が提供する「テーブルの履歴を取る」機能。SCD2(Slowly Changing Dimension Type 2)形式で、変更があった行を、古い行を残しつつ追記していく。今回 dlt 取り込みは多くの source を replace(毎回全件置き換え)で動かす方針にしたため、消えていく履歴を別途残しておく保険として dbt snapshot をセットで導入

    • パリティ検証: 移行前後で同じ入力に対して同じ出力が得られるかを比較する作業。「Airflow 時代の DAG が出していたテーブルと、Dagster で書き直したものが一致するか」を確かめる

    • Big Bang 移行: 一気に全部切り替える移行方式。失敗すると全部止まるので、規模が大きくなるほど怖い

    • 段階移行: 範囲を区切って少しずつ切り替える移行方式。安全だが期間と手間がかかる

    • Terraform: クラウドインフラ(GCP のサービス・IAM・ネットワーク等)をコードで管理するツール。「Composer インスタンスを削除」などの操作を、ボタンではなくコードの変更 → apply で行う


    “引っ越し” の何が難しかったか

    500 以上のテーブルがあるデータ基盤を引っ越すとき、一番怖いのは 「動いている Airflow が止まると事業に影響を及ぼす」 ことでした。

    うちのデータ基盤は、

    • 営業活動で使うレポートの自動生成

    • 週次で BigQuery のデータを使って定量分析をおこない、異常が無いか等を Slack に通知

    • 個々人が必要に応じて Claude を通じて分析

    など、人間や AI をデータの消費者として、幅広く使われています。「明日からデータ来ません」は許されない世界です。

    そして、Airflow と Dagster は同じ仕事をする道具とはいえ、内部の動き方は別物。一気に切り替える Big Bang 移行をやると、

    • 切り替え当日に何かバグれば、その日のデータが全部なくなる

    • 元に戻そうにも、Dagster で書いたコードを Airflow に戻すのは現実的じゃない

    • どこで何がおかしくなったか、500 を超えるテーブル分の影響範囲を一瞬で把握するのは無理

    ということで、段階移行を選ぶしかありませんでした。

    画像

    ちなみに先に全体感の数字を出しておくと、Phase 1 の DEV 着手から、Phase 4 で Composer を畳むまでの全行程は 約 4 週間 でした。Phase 1 ~ 2 (DEV / STG) で前半 2 週間、Phase 3 ~ 4 (PRD 切替 ~ Composer 廃止) で後半 2 週間(Phase 4 の観察期間込み)、というざっくりした内訳です。


    だから 4 段階に分けた(Phase 1 〜 Phase 4)

    段階移行といっても、約 500 テーブルをどう区切るかが問題です。うちではテーブル単位で区切るのではなく、 実行環境ごとに段階を上げていく やり方を取りました。

    画像

    「環境を 1 段ずつ上げる」というやり方は、 前の環境で見つかった問題を次の環境までに潰せる のが利点です。逆にいうと、PRD で初めて見える問題(特にデータ量起因のもの)は、結局 PRD でしか見えません。これが後で効いてきます。

    画像

    Phase 1〜2:DEV / STG での E2E 検証

    最初の 2 段階は、コード書いて、動かして、Airflow 時代の出力と突き合わせる、の繰り返しです。
    DEV と STG では、Airflow と Dagster の 両方を動かして突合することができました。同じソースから同じテーブルが作られるか、行数とハッシュで比較。これが第 1 回で軽く触れた「パリティ検証」です。
    パリティ検証で見つかった差分は、たとえばこんなものです(全部実例)。

    • スキーマドリフト(カラムが増えた・減った)の Slack 通知が Dagster 側で漏れていた

    • Dagster と Airflow でデータ加工を実行するプログラムの起動条件が異なり、うまく起動しなかった

    • CloudSQL のテーブルが「無変更だったとき」の skip 判定が Dagster 側でなかった

    5 件ほど見つかって、3 件は本番デプロイ前に必須修正として潰しました。「動くは動くけど、Airflow 時代と少しずつ違う」を地道に詰める作業です。地味ですが、ここを飛ばすと PRD に出してから「あれ、Slack に通知来ないけど…」となります。DEV / STG 合わせて約 2 週間 をこの作業に充てています。


    Phase 3:PRD デプロイで起きたこと(3 日 + さらに 3 日)

    ここがこの記事の山場です。
    DEV / STG で固めた構成を PRD に持っていって、 Bronze 層(生データの一次格納)を Airflow から Dagster に切り替える 作業をしました。

    切り替えにあたって取り込み方式も整理して、 多くの source を dlt の replace(毎回全件置き換え)で動かす一方、消えていく履歴は dbt snapshot で別レイヤーに残す 、というセットを採用しました。replace は実装も運用もシンプルだけど履歴が消えるので、その弱点を snapshot で補う形です(一部の source は性質に応じて append や merge を使い分けています)。

    そして元々の計画では「Airflow と Dagster を 1〜2 週間並行稼働させて、安全を確認しながら切り替える」つもりでした。

    ところが、並行稼働が技術的に不可能だったことが PRD のデプロイ直後に判明しました。

    理由は構造的なものがいくつか:

    • Airflow と dlt で GCS の JSON 構造が違う: Airflow 時代は JSON カラムにそのまま入れていたけど、dlt は __segments / __pages のような子テーブル(ネストされた配列を別テーブルに分割したもの)に展開する。同じ場所に両方書くと、後段の dbt が壊れる

    • CloudSQL のスキーマが移行中に変わる可能性: Airflow 時代と Dagster 時代で「テーブルにカラムが増えた」ときの判定ロジックが違うため、変更が入るとどちらかが落ちる

    このあたりが PRD の本番データを前にして初めて見えてきたので、「並行稼働は諦めて、ワンショットで切り替える」運用に方針転換しました。具体的には、

    1. PRD の Bronze 層を CREATE TABLE AS SELECT で全件 snapshot(バックアップ)として丸コピー

    2. Airflow を完全停止

    3. Dagster で全テーブルを再構築

    4. 何かおかしければ snapshot から戻して Airflow を unpause(復活)

    という手順を組みました。

    そして、ここで 3 日止まりました。

    念のため補足しておくと、ここで止まったのは 社内利用のデータ基盤(分析・レポーティング向け) の更新で、お客さま向けプロダクトのサービス自体には直接影響していません。

    派手な障害が起きたわけではありません。 単純に、本番のデータボリュームが想定より大きく、Dagster での再構築に思ったより時間がかかった だけです。STG では数十分で終わっていた処理が、PRD のスケールでは約半日近くかかるテーブルがあったり、依存関係を辿って後段の集計まで全部回し直すのに合計 3 日かかったりしました。

    社内チームメンバーには途中で、データ更新が止まっている旨をアナウンスしました。申し訳なかったのですが、辛抱強く待っていただきました。 「STG で測った時間 × N 倍 = PRD でかかる時間」みたいな単純なスケール換算は通用しない、というのがこのときの一番の学びでした。

    そして、データ更新の停止は 3 日。その後の修正作業も含めると合計約 1 週間かかりました。切り替え自体は完了したものの、その後さらに約 3 日、後段の dbt モデルで残っていた小さなエラーを潰す作業に費やしました。データ移行のときにスキーマがちょっとだけ変わっていた箇所 (主キーの型が変わっていたとか、特定の列が NULL を許容するようになったとか) を、本番のデータを見ながら 1 つずつ直していく作業です。これも「PRD じゃないと見えない問題」の一部で、「切り替えが終わった = 移行完了」ではない、という当たり前のことを、改めて思い知らされました。

    画像

    Phase 4:Composer を畳む

    PRD で Dagster が安定して動いているのを数日見届けて、最後に Cloud Composer を畳みました。これは比較的淡々と進みました。

    • Composer の DAG を全部 disable(無効化)

    • 約 1 週間放置して、誰からも「あのデータ来なくない?」が出てこないか確認

    • Composer インスタンス自体を Terraform で削除(コード上の定義を消して terraform apply で反映)

    第 1 回に書いたコスト削減は、ここで初めて実現します(具体的な数字は第 3 回で答え合わせします)。


    学んだこと

    長くなったので、3 つにまとめます。

    1. 並行稼働は “できる前提” にしない

    セオリー通りなら「移行中は並行稼働して、出力を比較しながら切り替える」が正解です。ただ、 ストレージレイヤー(GCS や DB)が共有されている場合、並行稼働そのものが構造的にできないことがある 。設計段階で「並行稼働できるか」を 真っ先に検証する べきでした。

    2. STG と PRD のスケール差は読めない

    データ量が 100 倍違えば、処理時間は 100 倍とは限らず、もっと延びることもあります(インデックスが効かなくなる、メモリに乗り切らない、など)。 PRD でしか見えない問題がある前提で、ロールバック手順を必ず用意しておく こと。うちの場合は「ワンショット snapshot + Airflow unpause」の二段構えがそれでした。

    3. “止める時間” は止める前にアナウンスする

    止まること自体は、事前にアナウンスし、社内・チームメンバーが「今は止まってる時間」と知ってさえいれば事故にはなりませんでした。
    怖いのは「止まってると気づかれない」こと。
    このあたりは途中からのアナウンスになったので、非常に反省している点です。


    おわりに

    「500 テーブル超を止めずに引っ越した話」というタイトルで書き始めて、最後の最後で 3 日止めてしまったわけですが、無事移行を完了することができました。
    データの更新は止まったけれど、ロールバック手順も用意していたので、致命的な事故にはなりませんでした。
    次回(第 3 回)は「Dagster の “ネイティブ統合” が効いた話(dlt / dbt + リバース ETL)」というタイトルで、第 1 回・第 2 回で何度か出てきた dlt(取り込み) と リバース ETL をどう導入したか、Dagster とのネイティブ統合がなぜ強力なのかを書きます。


    連載目次


    最後に

    まだまだ発展途上のデータ基盤。これからも生成AI・LLMを使った改善を続けていきます!
    データ基盤に興味がある方、LLMを活用した開発やデータ分析に興味がある方、ぜひお話ししましょう。


    ▼Scene Live 採用情報

    ▼bq事業のエンジニア採用

    この記事が参加している募集

     
     
    株式会社Scene Live・New Standard室のまっすーです。データエンジニア兼データサイエンティストとして、データ基盤作り・分析設計・LLMOpsまで幅広く取り組んでいます!

    あなたへのおすすめ