Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ZOZOにおけるデータマート集計基盤の成長と反省 / Growth on the Data ...

pokoyakazan
December 11, 2024
41

ZOZOにおけるデータマート集計基盤の成長と反省 / Growth on the Data Mart Aggregation System at ZOZO

pokoyakazan

December 11, 2024
Tweet

Transcript

  1. © ZOZO, Inc. 株式会社ZOZO 技術本部データシステム部 データ基盤ブロック ブロック長 奥山 喬史 -

    2018年4月 ~ 2022年1月: カカクコム(データエンジニア) - 2022年2月 ~ : ZOZO(データエンジニア) - BigQueryで構築されたデータ基盤の運用保守 - 個人活動: - 「ぽこやかざん」という名前でラジオ投稿したり大喜利したり - 「下町モルモット」というコンビで漫才したり - 日本一になりました!全日本アマチュア芸人No1決定戦 優勝 - 「アマ芸人日本一が決定!社会人コンビに栄冠「人生が動きそうなワクワクがあります」 昨年優勝者はR-1決勝で注目」というタイトルで、よろず〜ニュースに掲載( 2024年8月18日付) 2
  2. © ZOZO, Inc. 3 目次 - サービス紹介 - ZOZOのデータ基盤におけるデータ処理システム -

    データマート集計基盤とは - 2024年に追加されたデータマート集計基盤の新機能紹介 - dbt導入 - 後続データマート調査ツール - Backfill機能
  3. © ZOZO, Inc. https://zozo.jp/ 4 • ファッションEC • 1,600以上のショップ、9,000以上のブランドの取り扱い •

    常時102万点以上の商品アイテム数と毎日平均2,600点以上の新着 商品を掲載(2024年9月末時点) • ブランド古着のファッションゾーン「ZOZOUSED」や コスメ専門モール「ZOZOCOSME」、シューズ専門ゾーン 「ZOZOSHOES」、ラグジュアリー&デザイナーズゾーン 「ZOZOVILLA」を展開 • 即日配送サービス • ギフトラッピングサービス • ツケ払い など
  4. © ZOZO, Inc. 7 データマート集計基盤とは • データマート: ◦ データ基盤利用者が作成したSQLファイル内のクエリで日次更新されるBigQueryテーブル ※SQLファイルにはSELECT文のみ記述、UPDATEやDELETEといったDMLは書かない

    • データマート集計基盤: ◦ Cloud Composer(Google Cloud提供のApache Airflowマネージドサービス)上に構築 ◦ 1,100超のデータマートを依存関係を保ちながら更新していくシステム
  5. © ZOZO, Inc. 8 依存関係を保ちながら • 「FROM, JOINの後ろのマート」→「SQLを実行するマート」となるよう依存関係を構築している # table1.sql

    SELECT * FROM `project.dataset.existing_table1`; # table2.sql SELECT * FROM `project.dataset.existing_table2`; # table3.sql SELECT * FROM `project.dataset.table2`; # table4.sql SELECT * FROM `project.dataset.table1` UNION ALL SELECT * FROM `project.dataset.table3`; # table5.sql SELECT * FROM `project.dataset.table3`; (?i)(?<=FROM|JOIN)[\s \n]*`(.+?)` 正規表現で参照先データマートを抽出 例: existing_table[12]というソーステーブルと下記SQLのtable[1-5]というデータマートがある場合
  6. © ZOZO, Inc. 11 dbtの導入に至るまで 以下のような課題があった データマートの乱立 集計定義のばらつき 依存関係の洗い出しが困難 同じ受注でも基準日が

    違っているけどいいん だっけ...? この定義変えると、どんな影響 があるんだっけ...?いつの間に か勝手に参照も増えてるな こういう定義使いたいけど、 どのテーブル使えばいいんだ ろう?どこかで見たような...
  7. © ZOZO, Inc. 13 dbt導入によるデータマート整備 • 体系的なモデリングに則り品質担保されたデータマートをdbtで作成したい • 1,100超のデータマート全てをdbtモデル化したくない ◦

    SQLさえ書けば自動でデータマートを作成・更新してくれる既存システムは利便性が高い ◦ ビジネスサイドの社員も含む550人以上の利用者がいるため、dbtですべてモデリングし直す のは非現実的 • 2種類のデータマートを目的に応じて使い分ける ◦ SQLデータマート ▪ これまでのSQLによって更新されるデータマート ▪ レポーティング用途 ◦ dbtデータマート ▪ dbtによって更新されるデータマート ▪ 集計定義を統制して品質担保
  8. © ZOZO, Inc. 14 データマート集計基盤からdbtデータマート更新 • dbt単体ではできない実行制御: ◦ モデルごと自動リトライ ◦

    依存関係による待ち合わせ制御 • → 既にデータマート集計基盤でこれらの機構は実装済み • → データマート集計基盤でdbtデータマートの更新もできるようにする • また、dbtデータマートを参照するSQLデータマートが存在するため、1つのAirflow Dagに統一
  9. © ZOZO, Inc. 18 後続データマート調査ツール導入に至るまで • 後続データマート・後続データマートの参照者の洗い出しが大変 WITH table_jobs_meta AS

    ( SELECT referenced_tables.dataset_id as referenced_table_dataset_id ,referenced_tables.table_id as referenced_table_table_id ,destination_table.dataset_id as destination_table_dataset_id ,destination_table.table_id as destination_table_table_id FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION JOIN UNNEST(referenced_tables) AS referenced_tables WHERE DATE(creation_time, "Asia/Tokyo") >= DATE_SUB(CURRENT_DATE("Asia/Tokyo"), INTERVAL 90 DAY) AND DATE(creation_time, "Asia/Tokyo") <= DATE_SUB(CURRENT_DATE("Asia/Tokyo"), INTERVAL 1 DAY) ) ,nest1 AS ( SELECT DISTINCT "nest1" AS nest_level ,destination_table_dataset_id ,destination_table_table_id FROM table_jobs_meta WHERE referenced_table_table_id = 'SOME_TABLE' AND (referenced_table_dataset_id, referenced_table_table_id) != (destination_table_dataset_id, destination_table_table_id) --自己参照除外 ) ,nest2 AS ( SELECT DISTINCT "nest2" AS nest_level ,destination_table_dataset_id ,destination_table_table_id FROM table_jobs_meta WHERE (referenced_table_dataset_id, referenced_table_table_id) IN (SELECT (T1.destination_table_dataset_id, T1.destination_table_table_id) FROM nest1 AS T1) AND (referenced_table_dataset_id, referenced_table_table_id) != (destination_table_dataset_id, destination_table_table_id) --自己参照除外 AND (destination_table_dataset_id, destination_table_table_id) NOT IN (SELECT (T1.destination_table_dataset_id, T1.destination_table_table_id) FROM nest1 AS T1) ), nest3 AS ... 後続データマート調査クエリの一部(JOBS ビューから取得)
  10. © ZOZO, Inc. 19 Slack Slash Command から楽に取得可能に Slack でコマンドを打つだけ!

    • /datamart_downstream ${PROJECT}.${DATASET}.${TABLE} • /datamart_downstream_user ${PROJECT}.${DATASET}.${TABLE} (参照者も知りたい場合)
  11. © ZOZO, Inc. 20 Slack Slash Command から楽に取得可能に! 内部でやっていること •

    Cloud RunのエンドポイントをSlash Commandのリクエスト先に設定 • 各データマートの依存関係はAirflow(Cloud Composer)が保持しているのでAPIから依存関係を取得 • 取得した依存関係を整理してSlackに投げ返す
  12. © ZOZO, Inc. 22 Backfill機能導入に至るまで データマートの新規追加、スキーマ・集計定義の変更を行った場合、対応日以降のデータは溜まる しかし、対応日より前の過去データ作成は利用者自らが行う必要ある 過去データを作成例: 2024-01-01に新規追加されたデータマートについて考える •

    2024-11-01に集計ロジックを修正した場合 ◦ 2024-11-01からは新ロジックで集計 ◦ 2024-01-01 ~ 2024-10-31のデータは旧ロジックで集計されたデータとなる • → 2022-11-01 ~ 2024-10-31のデータも新ロジックで集計したい! → 過去データ作成のクエリは期間が広いため重い!他の分析クエリとバッティングして時間がかかる!
  13. © ZOZO, Inc. 24 反省点: Backfill機能はお金がかかる 対象データマートの過去分の集計を全てやり直すのでBigQueryのスロット費用が大きい 1日分の集計で200 Slot Hourかかるデータマートを2年分Backfillする場合:

    • 使用するスロット量 ◦ 200 * 365 * 2 = 146,000 Slot Hour • かかる費用 ◦ 146,000 * 0.06 = $8,760 ◦ ※ Enterprise Edition の料金($0.06 / Slot Hour)で計算 → 単純にBackfillを実行していくのは現実的ではない
  14. © ZOZO, Inc. 29 まとめ • ZOZOのデータ基盤には様々なデータ処理システムがある • その中の1つであるデータマート集計基盤に3つの新機能を導入した ◦

    dbt導入 ◦ 後続データマート調査ツール ◦ Backfill機能 • 語り尽くせなかった部分も多くあるので、BigQuery使っている方々はぜひお声がけください • 一緒にデータ基盤を開発していただけるデータエンジニアの方を絶賛募集中です!!