Algoage Tech Blog

Algoageの開発チームによる Tech Blog です

【連載】データ分析基盤をdbt・Snowflakeに移行する【設計・実装編】

こんにちは、Ops-dataチームの上村(@contradiction29) です。以前、弊社内で運用されているデータ分析基盤を移行するにあたり、設計の方針を練る記事を投稿しました。

tech.algoage.dmm.com

今回はその続きとして、移行プロジェクトの実際の進行に焦点を当てて記事を書いていきたいと思います。

はじめに

これまでのあらすじ:運用していく中でつらみがたまってきた弊社のデータ分析基盤。開発しづらいし、運用もつらいし、何よりこのまま運用を続ければ確実に停止してしてしまう。End of Service Life (EOSL) は目前に迫っています。移行するしかない状況です。

とはいっても、単純に移行するだけでは、現場のアナリストやエンジニア、社内ユーザー、そしてその先にあるクライアントのニーズに応え、事業価値に貢献することはできません。真の「価値」に貢献するためには「思想」が必要です。そういうわけで、まずは基本的な設計思想をゼロベースで考え直すところから始めました(くわしくは前回の記事参照)。再掲します。

原則1:データ分析基盤は、 変化するニーズに応え、迅速に価値を提供できるように設計する

原則2:データ分析基盤の運用にかかる労力が最小限となり、データ利用者への価値提供に集中できるように設計する

原則3:データ分析基盤の利用者への「分析者体験」の最大化を第一の判断基準として設計する

原則はできたので、次は実装…と行きたいところですが、仕事をしている以上、プロジェクトが完了する確率を可能な限り引き上げる必要があり、そのためにはリスクに対して正面から取り組む必要があります。リスクを扱う上では、「とるべきリスク」と「とってはいけないリスク」を分別し、後者については事前に排除するのが得策です。そのうえで実装に入るほうが最終的な完成度は高まるし、期限を短縮することが可能となります。

この記事では、移行プロジェクト開始前にリスク排除を目的として実行したことや考えたことについて振り返ったのち、実際に「曳光弾開発」(詳細は後述します)を用いて設計・実装したプロセスについて記述していきます。最小構成の構築が完了した後の肉付けを経て、実際に稼働できる状態まで持っていく過程についてまでを今回の記事のスコープとします。 先に全体像を示しておくと、以下のような構成になりました。詳細は後述しますが、以下の3点がポイントです。

  • ELTの構成になっている
  • ほぼフルマネージドなサービスを使い、運用にかかる労力なるべく減らしている
  • 開発者体験を重視したツールを利用し、開発をやりやすくしている

データ基盤の全体像

それでは中身に入りましょう。

プロジェクトの障害を事前に排除する

一口に「プロジェクト進行上のリスク」といっても、分類法や観点など、色々な見方があると思います。PMBOKに書いていそうなことを引用するのもアリですが、ここでは自分と弊社のEMさんとの会話をもとに、リスクをどのように分類し、対処していったかについて振り返っていこうと思います。

タイミングリスク

データ分析基盤の移行を実施する際、タイミングを考慮することは重要です。一般論ですが、すでに稼働しているシステムに対して、数か月かけて大規模な変更を加えることは躊躇される傾向があります。タイミングを間違えることは、メンバーやステークホルダーの離反の一因たりえるものです。

逆に言うと、タイミングをうまく合わせられれば自然とリスクは排除されることになります。自分がデータ分析基盤の移行を行う際に一番気を付けたのはこの「タイミング」でした。端的にいうと、移行を行うには絶好のタイミングではありました。理由は2つです。

  1. 5~6月にかけてデータ分析基盤の事故が多発したため、ステークホルダー間で事故の記憶が新しかった

    • 詳細は前回の記事を参照してほしいのですが、根本的な原因は既存システム運用のつらさによるものであり、技術スタックの入れ替えが解決策であることは明確でした
    • そのため、基盤をドラスティックに変更することの重要性を説明しやすいタイミングだったといえます
  2. Athenaのパーティション制限の問題により、このまま稼働を続けれEnd of Service Lifeを迎えることは明白だった

タイミングのリスクはすでに排除されていると考えてよさそうです。頭を切り替えて、ほかの種類のリスクに関して考えてみます。

時間切れリスク

Athenaのパーティション制限がある以上、時間切れは明確に存在しています。設計・実装に時間をかけすぎれば、移行しきらないうちにデータ分析基盤が停止し、現場でデータを必要とするユーザーにデータを届けることが不可能になります。

そうなると、時間のかかる開発手法は使えません。ではどうする?「曳光弾開発」を使えば早くできそうです。

脇道:曳光弾開発とは何?

話が脇にそれますが、「曳光弾開発」の中身について話しておこうと思います。

ざっくりいうと、曳光弾開発とは、end-to-endで動く最小構成をまずつくり、機能を拡充しながら段階的にニーズを満たしていく開発手法のことです。「曳光弾」は光を放ちながら飛ぶため、開発の過程や方向性を明確に示し、それを追いながら機能や性能を拡充していくというイメージからこの名前が付きました。(出典:『達人プログラマー』)

データ分析基盤の文脈でいうと、まず一つのダッシュボードを選び、そのダッシュボードを作るために必要なテーブルを作り、そのテーブルを作るために必要なデータソースの取り込み処理を実装し…のように、最小構成のend-to-endのパイプラインを作ります。まず一本、横に長い線を引くイメージです。次に、その横の線を増やしていき、最終的にすべての線を実装する、という方法です。

データ分析基盤の構築において、最も難易度が高いのは「一番最初のend-to-endのラインの構築」です。逆にいうと、end-to-endのラインを拡充するのは相対的に難易度が低いといえます。曳光弾開発の手法を使えば、リスク(難易度)の一番高い部分から順に解決していくことになるため、リスク低減の観点から最適な手法であると考えました。

技術的リスク

リスクの話に戻ります。今回の移行では、大規模な技術の入れ替えを行うことを想定していました。加えて、筆者(移行時点では新卒2年目)はデータエンジニアとしての経験はあまり豊富ではありません。経験の浅いエンジニアがドラスティックな技術の入れ替えを行う場合、技術的なリスクがないと考えるほうが難しいでしょう。具体的には以下のようなものです。

  • 選択した技術では、非機能要件や機能要件を満たせない
  • 技術選択を誤れば構築に時間がかかり、時間切れになる可能性がある

確実に要件を満たせることを保証しつつ、高速に実装できる方式を選ぶ必要があります。曳光弾開発がまさにそれです。

人手不足リスク

移行に伴い多くの作業が発生するため、人手が足りなくなることが想定されます。今回のケースでは期限の超過がデータ分析基盤システムそのものの停止を意味するため、人員不足による遅れは極力避ける必要があります。

対応としては、以下のような方針とすることとしました。

  • 極力手戻りを抑え、かかる人手を最小限に抑える
    • やっぱり曳光弾開発
  • 人手が不要なところは自分一人でやる*1一方で、人手が必要になったタイミングでチームメンバーの助けを借りる
    • チーム内へのスキル普及も同時にできるため、一石二鳥です
    • 事前に頭出しや説得を念入りに行う必要があります

他にも、自分が通常の業務をさばけない間は、ほかのメンバーにフォローしてもらう体制を組んでいただいたりしました。非常に感謝しています。

資金リスク

データウェアハウスやSaaSの費用がかさみ、想定を超えてしまうリスクです。コスト超過それ自体リスクではありますが、ステークホルダーからの信頼を失うリスクもあるので、極力注意したほうがよいでしょう。金と政治が密接な関係にあるのは歴史が示す通りです。

対応策はシンプルです。

  1. 最近のデータエンジニアリング系の製品には無料期間があるものが多いため、無料期間中にしっかり見積もりを立てるようにしました
    • 例えばFivetranはコネクターごとに14日分の無料期間があります。その間にMAR(Monthly Active Record: Fivetranの課金単位)の見積もりを立てておきます
    • Snowflakeには30日分の無料期間と$400分のクレジットがあります。その間に、ウェアハウスの利用料の見積もりとストレージ費用の見積もりをざっくり出しておきます
    • 曳光弾開発とも相性が良いです
  2. 求められなくても、コストに関する報告は優先して実施するようにします
    • 報告をしっかりしておくだけで、怒られが発生するリスクはかなり減ります

政治リスク

政治的な問題により、移行プロジェクト自体が尻切れトンボになってしまうリスクもあります。具体的には以下のようなリスクです。

  1. チーム内メンバーの協力が得られない
    • 人手を借りられず、時間切れになる
    • 新たな技術を導入しても普及しない
    • 通常業務に忙殺され、移行にリソースを割けない
  2. ステークホルダーの合意が得られず、移行自体が中止になる
    • SaaSの利用に対して承認が得られない
    • 「鶴の一声」で移行自体が立ち消えになる

地道に対応していきましょう。メンバーへの頭出しや根回し、個別の説得を実施し、協力を取り付けるようにしました。「メンバーのスキルのキャッチアップを補助する」とあらかじめ宣言しておくのも有効です。開発の進捗は適時共有し、今どのような状況なのかが把握されている状態を作っておくのがよさそうです。

結論

様々なリスクを考慮した結果、「曳光弾開発」のスタイルで実装することを決めました。利点として魅力に思えたのは以下のような観点です。

  1. 動くことを検証しながら実装できる
    • 機能要件・非機能要件を満たせることを確実に保証しながら進むことができる
  2. 動くデモを作れる
    • ユーザーからの反応を得ながら開発できる
      • 特に、データ分析チームにはエンジニアが一人しかいないため、アーキテクチャに関するレビューが不可能な状態でした
      • 実際に動くプロダクトなら非エンジニアのアナリストでもレビュー可能です
    • 現状の共有がスムーズに行えるため、政治的なリスクを抑えられる
  3. 手戻りを抑えられる
    • 実装期間を最小限に抑えられるため、時間切れのリスクを抑えられる
  4. コストを図りながら実装できる
    • 資金リスクを抑え、政治的なリスクを抑えられる

方針が固まったところで、次は実際に開発していく過程を振り返っていきましょう。

実際の設計・開発

方針を前提に、実際の技術選定と実装の過程を振り返っていきます。

まず一番最初に決めるのはデータウェアハウスです。選択肢が少ないから決めやすいのに加えて、他の構成要素への影響が大きいため、一番最初に決めておくのが良いと判断しました。次に、データソースからダッシュボードに向けて、順番に技術選定を実施していきます。

では、技術選定の過程を振り返っていきましょう。最小構成の構築にかかった期間は一週間ほどでした。

データウェアハウスの決定 : Snowflake

バックエンドがAWSであり、ログがJSON LINES形式の形でS3バケットに出力されるため、同じAWS圏内で利用可能なものにする必要がありました。また、弊社の分析は基本的には日次バッチですが、一部の加工前データを利用した分析はリアルタイムで実施する必要があります。

なのでSnowflakeで確定です。Snowpipeもありますからね。BigQuery Omniを利用するよりも楽に設定できそうなのも魅力でした。

Snowflakeについてざっくり理解したい方はこちらをご覧ください。

www.youtube.com

この段階で、Snowflakeのアカウントを作成しておきます。無料期間を最大限活用していきました。

docs.snowflake.com

加工前データの取り込み:Fivetran + Snowpipe

データウェアハウスが確定したので、データの取り込み手段を考える必要があります。なお、dbtを導入することは確定していたため、ELT*2の構成になることが前提になっています。

データソースとしては3種類あり、それぞれ違った取り込み形式を利用してSnowflakeに取り込んでいきます。

Amazon S3バケット上に置かれたJSON Lines形式のファイル

ユーザーの行動ログはKinesis Firehoseを経由してS3バケット上にPUTされます。なお、分析のユースケース上、Kinesis Firehoseから出力されたデータはリアルタイムでクエリ可能な状態になる必要があります。

選択肢ですが、データウェアハウスとしてSnowflakeを利用しているため、事実上Snowpipe以外の選択肢がありません。Snowpipeで取り込みます。

docs.snowflake.com

なお、外部ステージ→Snowpipe→ローデータ格納テーブルの対応関係はTerraformでモジュール化しておきました。実運用に移行するうえでは、複数の対応関係を作る必要があるため、あらかじめモジュール化しておくと素早く実装できそうです。

Amazon RDS for Aurora MySQLインスタンス

プロダクト本体のバックエンドとして利用されているAmazon RDS for Aurora MySQLインスタンスSnowflakeに取り込みます。AirbyteかFivetranで迷いましたが、RDSのコネクタがあり、管理に手間がかからないFivetranを選びました。

www.fivetran.com

踏み台サーバーを経由した接続に時間がかかりましたが、Product部の纐纈さんと石塚さん*3に手伝っていただいたため、速攻で何とかなりました。逆に、接続の確立が終わってからはほとんどすることがありませんでした。

Fivetranにはコネクタごとに2週間の無料期間があるため、MARを図りながら料金を見積もっておきます。FivetranはActive Record (更新のあったレコードのような概念)の月次集計で料金が変わる従量課金型のツールです。コネクタを接続してから1週間ほどたつと勝手に見積もってくれたりします。

www.fivetran.com

記事執筆時点でFivetranを利用し始めて2か月ほど経ちますが、とにかく手間がかからなくてよいツールです。テーブルの追加やカラムの追加に自動で対応してくれます。Airbyte Cloudより料金は高いですが、運用をスマートにこなしつつ、ユーザーのデータのニーズに応える体制を作るうえでは必要なコストとしてとらえています。

Notion, Google SpreadSheetなどの手入力データ

弊社では、プロダクト本体では回収できないデータをGoogle SpreadSheetやNotionに入力してもらい、そのデータをデータ分析基盤内で利用しています。もともとAWS Lambdaを利用してCSV形式に落とし込んでS3上にアップロードする形で運用していたため、既存プログラムを修正するのみで対応完了です。

データの変換:dbt

データの変換ツールとしてはdbtを利用します。

www.getdbt.com

魅力に関しては既に多くの方が書かれているのでここでは割愛し、弊社のデータ分析チーム内での議論において、特に何の機能を魅力としてとらえていたのかだけ書こうと思います。さっと上げると以下のようなものです。

  • リネージュ把握機能
  • ドキュメント機能
  • ローカルでの実行機能
  • マクロの利用

運用して2か月たちますが、現場では特にリネージュ把握機能が人気のようです。ちなみに、筆者が初めてdbtを使ったときは感動して涙が出ました。良い時代に生まれてよかった…

dbtの実行管理ツール選定の観点

Findyで特集が組まれるくらい流行りのdbtですが、dbtのオーケストレーションには選択肢が多く、悩ましいポイントでもあります。dbtのDAG実行管理をどのように行うかにより運用時のコストが変わります。考慮した点としては2つありました。

特定のモデルの実行が失敗した場合、素早く復旧することが可能か?

具体的には以下のような点です。

  • 特定のモデルを選択して実行することが可能か
  • 特定のモデルの下流のモデルのみ、もしくは上流のモデルのみを選択して実行できるか

仮に上記のようなことを行えず、単純に dbt run するしかない状況だと、一つのモデルでエラーが発生した場合でも全てをやり直す必要があり、復旧時のオペレーションに時間がかかります。データは水物であり、どのモデルにも潜在的にエラーを起こす可能性はあるため、柔軟にモデルを選択して実行を管理できる必要があります。

特定のモデルを連続する期間にわたって再実行することが可能か?

例えば、日次で実行しているインクリメンタルなモデルがあったとします。そのモデルの実行を2023-09-01から2023-09-08までの期間だけやり直したい、ということは結構よくあります。いわゆるbackfillですね。

dagster.io

上記記事によると、backfillの定義は以下のようなものです。

For example, you have a table, and each day, you add records to it that correspond to events that happened during that day. Backfilling the table means filling in or overwriting data for days in the past.

(日本語訳) 例えば、あるテーブルがあり、毎日、その日に起こった出来事に対応するレコードを追加するとする。テーブルのバックフィルとは、過去の日数分のデータを埋める、あるいは上書きすることを意味する。

選ばなかった選択肢

リネージュを考慮した実行が可能であり、なおかつバックフィルが可能な手段となると、選択肢は3つほどありましたが、最終的にはDagster Cloudを利用する方針としました。考慮はしたが選択しなかった選択肢としては以下の2つがありました。

Airflow + BashOperator

  • Airflowをベースに、BashOperatorを利用して個々のモデルごとに dbt run --select model_name をしていく実装です。Airflowのクラウド環境を提供するAstronomer社のブログで公開されていた手法です。

    www.astronomer.io

  • すでに運用知見があるAirflowを利用できるのはメリットではありました

  • しかし、ブログを見た限り、実装が重くなりそうなため、あまり気乗りしませんでした

dbt Cloud

  • 筆者も個人的に利用しており、dbtの範囲内だけでオーケストレーションするなら良い選択肢だと思います
  • しかし、弊チームではデータソース取得処理の中でAWS Lambdaなども利用しています。最終的にはそれらを含めたオーケストレーションまでやりたいと考えているため、力不足感がありました

なお、ちょうど移行作業を実施していた7月ごろ、Astronomer社からCosmosパッケージが発表されました。このパッケージを利用する手段もありましたが、時期の都合上、技術選定の段階では考慮に入れることができませんでした。

www.astronomer.io

Dagster Cloudを利用する

メリットとデメリットを天秤にかけた結果、Dagster Cloudを利用して実装することに決めました。

メリット

モデルを展開したうえで実行管理ができる

  • わずかな行数のコードを書くだけで、dbtのprojectディレクトリ配下にあるモデルを取り込むことが可能です

    一部伏字になっていますが、実際のパイプラインの一部です

  • 特定のモデルを選択して実行することも可能ですし、特定のモデルの下流のみ・上流のみを選んで実行することも可能です

    上流・下流モデルに絞ったモデルの選択が可能

バックフィル・オペレーションが楽

  • ものすごく簡単です。一つあるいは複数のモデルをGUI上で選んで、期間を選択するだけです。下の画面で、右下にある「Launch 479-run buckfill」を押せば、479日分のバックフィルが実行されます

    バックフィル画面

開発しやすい

  • ローカルで実行とブランチデプロイが可能なため、Jobの開発がすごく簡単です。Dagster Cloudにおけるブランチデプロイ機能を利用すれば、プルリクエストごとにクラウド環境を作れるため、検証・開発が非常に容易になります。詳しくは公式ドキュメントを参照してください

    docs.dagster.io

  • SQLをちょっと直す程度では使わない機能ですが、新たなJobの開発など、データエンジニアリングの領域の業務では非常に有用な機能です

  • また、dagsterは日本語の文献が少なく、概念も独特なため学習の難易度は高いのですが、開発が簡単なので高速でフィードバック・ループを回しながら学習できるという利点もあります

サーバーレスな実行環境を作れる

  • Dagster Cloudのサーバーレス版を使えば、コンピュートを実行する環境の管理が不要になります。Airflowに対するMWAAのような感じです

    docs.dagster.io

デメリット

学習コストが高い

  • dagsterの公式ドキュメントを読んでみるとわかると思うのですが、dagsterには独特な概念が多く、Airflowなどの既存のDAG実行管理ツールに慣れたエンジニアでも学習には苦労するツールです
  • しかし、開発しやすいため、学習のためのフィードバック・ループを回しやすく、学習コストの高さを打ち消すことが可能であると考えました
  • (追記)Dagster Universityという公式のラーニングコースもあるようです

    courses.dagster.io

実際の活用事例が少ない

  • dagsterは導入事例が少ないため、意図しない挙動が起こった場合にググってもようわからん状態になりがちです
  • しかし、コミュニティによるサポートがあるため、最悪そこに投げれば何とかなるかもと思います。ならないかもしれませんが

結論

デメリットは確実にあるわけですが、それを補って余りあるメリットがあると判断したため、dbtの実行管理はDagster Cloudで実施することに決めました。

Dagster Cloudにも無料期間があるため、無料期間を利用して技術検証を行いました。dbtのモデルを取り込んだり、Pythonを書いたりできるかを検証していきます。いかんせん導入事例が少ないため、公式ドキュメントとGitHubのIssue、およびライブラリの実装を見ながら、なんとか運用できるラインまで持っていきます。CD周りは自動で生成してくれるGitHub ActionsのYAMLファイルを利用しました。もちろん、無料期間内に費用の見積もりを出しておくのも忘れずに。

最終的な設計図と肉付け

最終的な設計図は以下のようになりました。

データ基盤の全体像

プロトタイプの構築が完了したため、最も難易度とリスクが高い個所をクリアすることができました。あとは「肉付け」の過程を通して、実際に利用できるデータ分析基盤を構築していきます。やるべきことは主に二つです。

まず、S3上に存在する加工前データの生データをSnowflake上に取り込む必要があります。Snowflake-connector-pythonを利用したプログラムを書いて実行し、夜間に実行して完了しているようにしました。特筆するところはなさそうなため省略します。

docs.snowflake.com

次に、既存のSQLをdbt+Snowflake記法に書き直したうえで、移行する必要があります。こちらに関しては、dbtとSnowflakeの勉強会を開き、チームメンバーに作業を分担してもらいながら実装しました。こうすることで、作業の並列化して実装期間を短縮しつつ、チームへのスキル普及を行うことが可能です。

おわりに

実際に利用可能なデータ分析基盤の構築が完了しました。

話は変わりますが、漢の将軍韓信は河を背にして陣をひき、兵たちを奮い立たせ、10倍の敵を打ち破ったといいます。あえて退路を断つことが有効であることは、データ分析基盤の移行に関しても同じです。過去に使っていたGlue Jobをすべて削除し、Glue Catalogを吹き飛ばし、MWAAの環境を消去しました。これでもう退路はなく、前に進む以外の道はなくなりました。

データ分析基盤を移行した結果

最後に、データ分析基盤の移行の結果を取りまとめて記事を締めくくろうと思います。

パイプライン実行時間が約30倍高速になる

パイプラインの実行時間は2時間50分から5分に短縮されました。原因は複数ありますが、以下の2つが大きい思っています。

  • 時間のかかる処理がなくなったこと
    • 具体的には、Glue JobおよびGlue Crawlerの処理が無くなったこと
  • Snowflake自体の実行が早いこと

ウェアハウスのマルチクラスタ化やサイズ拡大を実施すれば、将来的にパイプラインが拡大してもこの速さを維持できる想定です。すごい時代だ…

開発の速度が(体感)10倍くらい速くなる

次に開発の速度ですが、変更を加えるまでのスピードが体感10倍くらい早くなったと思います。時間を図っているわけではないので正確なことは言えませんが、考えられる要因としては以下のような原因がありそうです。

  1. Gitのフローがgit-flowからGitHub-flowに変更になり、変更手順がシンプルになったこと
  2. ブランチデプロイが可能になり、データエンジニアリングのコストが下がったこと
  3. ローカルでのテスト実行が可能になり、検証が容易になったこと

いずれもdbtとDagster Cloud, そしてSnowflakeの組み合わせで実現が可能になったものです。

運用の労力削減

最後に、運用のコストもかなり下がりました。

  1. 運用コストの高いGlue Job (Spark)を排除し、ほとんどの変換処理をSQLで統一したため、チーム内の非エンジニアメンバーでも保守・運用できる範囲が広くなった
  2. エラー発生確率の高いGlue Data Catalogを排除できた
  3. バックフィルオペレーションの手順がシンプルになった
  4. 開発が容易になったたため、「運用を楽にするための開発」がしやすくなった

結果的に、データ分析基盤の移行によりチームのケイパビリティは高まり、より多様なニーズに応える体制が整いました。運用のコストが削減され、データを利用して事業価値に貢献するための「余力」が増えたともいえます。データ分析基盤自体はよりアジャイルなものとなり、浮かせた運用コストでデータによる価値向上にコミットできる分が増え、データ分析者の体験も向上させることができました。

今後は、データ分析チーム以外のメンバーでもSQLを書いたりできるように、データカタログを充足させたり、テーブルを使いやすくしたり、データガバナンスを強化したりしていきたいと考えています。まだまだデータ利用者側のニーズに応えきれているわけではないので、地道にフィードバックを受け取りながら改善していきたいです。

*1:データ分析チーム内にはエンジニアが自分しかおらず、技術選定や難関になりがちな初期設定、設計などを担えるのは筆者しかいない状態でした

*2:Extract, Load, Transform : とりあえず生データをデータウェアハウスに突っ込んどいて、あとはよしなに変換しよう!という考え

*3:詳細はこちら:https://tech.algoage.dmm.com/entry/2023/09/13/133111

*4:と2023年9月のSnowflake Data Cloud World Tourの基調講演で聞きました