Tabelog Tech Blog

食べログの開発者による技術ブログです

食べログのデータ基盤にdbtを導入している話

はじめに

はじめまして。食べログ開発本部技術部の齋野です。早いもので入社してから4ヶ月ほどが経ちました。「データサイエンスチーム」というチームに所属しており、食べログのデータ基盤の開発、保守運用を担当しています。

現在、食べログのデータ基盤にdbt1を導入する計画が進行中です。

この記事では主にデータエンジニアリング職の方に向けて、現在稼働中であるGoogle Cloud上のデータ基盤にdbtを導入する際、移行に伴うデグレやオーバーヘッドを避けるための工夫について、食べログの事例をもとに紹介します。

稼働中のデータ基盤にdbtを導入したい

SQLを効率的に書きたい、データ変換処理の依存関係やメタデータを効率的に管理したいといったニーズに応えてくれるdbtは、データ基盤開発において非常に魅力的なツールであり、今後も導入事例が増えていくことと思います。

「既にデータ基盤はあるけど、データ変換処理にdbtを導入したい」というケースも多いのではないでしょうか。もう少し具体的な要件としては、BigQueryのようなDWHが存在し、ELTが動いていてBIとも連携している状態で、Tの部分をdbtを使った実装に切り替えたいというものです。スクラッチでデータ基盤を構築する場合と違って、既にユーザが存在し、現役で使用されているデータ基盤にdbtを導入する際には、スムーズに移行できるよう注意すべきポイントがいくつかあります。

今回取り上げるのは、運用フローの変更に伴うオーバーヘッドやユーザ影響を低減したいという点です。

食べログでは、データ基盤のELT開発は私たちデータサイエンスチーム内のデータ基盤開発メンバーが担当していますが、BIレイヤーの管理はデータ基盤ユーザ各自がそれぞれ行っています。データ基盤のユーザは技術職、ビジネス職を問わず幅広く存在しており、同じくデータサイエンスチーム内のダッシュボード構築を担当するメンバーや、ビジネスサイドのメンバーなどが該当します。BigQueryをインターフェースとしてユーザ自らがダッシュボードやBIを構築するというセルフサービス運用になっており、このような環境の中でdbtを導入するに際して、できるだけユーザへの影響を抑えるための工夫が必要です。

食べログデータ基盤のELTについて

食べログのデータ基盤はGoogle Cloud上にあり、DWHとしてBigQueryを使用しています。

データの抽出・ロード(EL)はEmbulkが、変換(T)はCloud Composerで起動するApache AirflowのBigQueryExecuteQueryOperatorを用いたデータ変換処理が担っています。

データマート層のテーブルのほとんどは、更新頻度ごとに区切られた日付パーティションテーブルです。Cloud Composerのバッチ処理は、最新パーティションのデータだけを作成します。例えば、Adobe Analyticsのようなトランザクションデータが新しくデータレイク層に追加されたら、増分に対応した最新パーティションがデータマート層に追加更新されていくという具合です。

このような稼働中データ基盤のT部分にdbtを導入するというのが、今回のシナリオです。

切り替えのフローについて

初めに検討したアプローチは、「dbtを使って同じテーブルをもう一つ用意し、BI側の向き先を切り替える」というよくあるフローです。

  1. 現行のデータ変換処理で作られるテーブル(旧テーブル)と同じ内容のテーブル(新テーブル)を、dbtを使ったデータ変換処理で別途作成する。
  2. 新テーブルの作成処理に問題がないこと(旧テーブルと新テーブルのデータに差分が無いか等)を確認する。
  3. 旧テーブルを参照しているダッシュボードを新テーブルに書き換えるなど、BIレイヤーの設定を合わせる。
  4. 旧テーブルを作成する処理を停止する。

最初の切り替えフロー案

このフローには、以下のような問題点があります。

BIレイヤーの設定変更コストが掛かる

食べログの場合、データマート層のテーブルの数は250程度とそれなりの数があります。旧テーブルを参照しているダッシュボードを一つ一つ開いて、設定を書き換えるというのは中々に骨の折れる作業です。

ダッシュボードを全てコード管理しているという場合なら楽な方法があるかもしれませんが、多くの場合は手動での作業となるでしょう。BIレイヤーと一言に言ってもTableauからVertex AI Notebooksまでユーザによってツールが様々であり、対応方法も多岐に渡ります。また、作業のためには「どのテーブルがどのBIから呼び出されているのか」という情報が必要となりますが、そもそも、データリネージが無いからdbtを導入しようとしているのに、導入の過程でDWHとBIとのデータリネージが必要になるというのも堂々巡りの感があります。

このアプローチで進める場合、現実的には以下のような作業が必要になると想定しました。

  1. BigQueryのINFORMATION_SCHEMAを使い、旧テーブルを参照しているクエリをリストアップする。
  2. 旧テーブルと新テーブルの対応表を作り、ユーザ自身でBIの参照設定を変更してもらうよう対応期限を設けてアナウンスする。
  3. 1のリストが無くなるまで経過を見る。または期限が切れたら旧テーブルの更新を停止する。

ユーザに理解と対応を求める必要があり、計画通りに進めてもそれなりの作業ボリュームがあることが見込まれる上に、ユーザの対応漏れなどによってデグレが生じる懸念があります。

新テーブルにデータを補完する手間が掛かる

旧データ変換処理で作成された過去パーティションのデータも参照したい場合、新テーブルにデータを補完する手間が掛かります。BIの設定変更と同様に、テーブルの数が多ければコストも大きくなります。

移行前後で同じテーブルを使う

こうしたデメリットを勘案して新たに検討したのが、「移行前後で同じテーブルを使う」というフローです。

  1. 現行のデータ変換処理で作られるテーブル(本番テーブル)と同じ内容のテーブル(一時テーブル)を、dbtを使ったデータ変換処理で別途作成する。
  2. 一時テーブルの作成処理に問題がないこと(本番テーブルと一時テーブルのデータに差分が無いか等)を確認する。
  3. 現行のデータ変換処理を停止し、dbtを使ったデータ変換処理の向き先を本番テーブルに変更し、次のパーティションからはdbtを使ったデータ変換処理で作成されるようにする。

二番目の切り替えフロー案

このフローでは、移行後もユーザ目線では今までと同じ名前のテーブルを参照でき、前述のようなBIの設定変更や過去パーティションのデータ補完などの手間が必要ないというのが最大のメリットです。

もちろん一長一短はあります。最初に挙げたフローと比べると、両者の間にはELTとBIの関心ごとをどこで分けているかという違いがあります。例えば、最初のフローにしかないメリットとして、新しいデータ変換処理への切替後に何か問題が見つかった場合、旧テーブルを作成する処理を停止する前であれば、BI側で参照するテーブルを元に戻すことですぐにロールバックできるというものが挙げられます。

例えば、データ変換処理のダウンタイム要件が非常に厳しいといった場合には、手間をかけても前者を取るメリットがあるかと思います。今回のdbt導入に際しては、データ変換バッチの頻度が最も短いもので日次ということもあり、移行に伴うオーバーヘッドを避けることを優先し後者を採用することとしました。

実装について

簡単に、実装方法について紹介します。

dbtの実行環境としては、Cloud Composer上からastronomer-cosmos2を経由して実行しています。 余談ですが、元々AirflowのOperatorでデータ変換処理を実装していたということもあり、DAGファイル上では、Operator単位でcosmosの実装に切り替えるだけで良いというのが、コードレベルの実装がやりやすく嬉しかった点です。また、テーブルの差分確認をdbt testとして行うことで、cosmosのtest機能を使って漏れなく差分確認を行うこともできた点も助かりました。

パーティション単位での作成については、dbtのincremental modelを使い、airflow側から渡した日付変数をdbtのvariableとして指定することで実装しています。以下のような例になります。

{{
  config(
    materialized = 'incremental',
    incremental_strategy = 'insert_overwrite',
    partition_by = {
      'field': '_target_date',
      'data_type': 'date',
      'granularity': 'day'
    },
    -- quote_varは前後にシングルクォートをつけるだけのmacroです。
    partitions = [quote_var(var("target_date"))]
  )
}}

SELECT ...

データ変換処理の向き先を変更する際には、dbt_project.ymlの設定変更で作成先のデータセットを変更し、旧DAGの終了日と新DAGの開始日を同日にするというPullRequest一本でできるのも嬉しいポイントです。

まとめ

いかがだったでしょうか。稼働中のデータ基盤にdbtを導入したいという場合の一助となれば幸甚です。

食べログデータ基盤へのdbt導入自体は現在絶賛進行中で、メタデータ活用によるデータ利用の活性化や、データマネジメントの推進といった本来のゴールはそのまた先に待っています。 いつか、そうした先のステップである施策を進めた時の話や、その際にdbtがどう役に立ったかなどについても投稿できればと思います。

明日は朽木さんの「開発中に感じた「ツラみ」は設計改善のチャンス~負債を生まない設計方針を立て、新規案件に活かした話~」です。ぜひご覧ください。