Slide 1

Slide 1 text

©MIXI 複数タイトルのための省力・共通化さ れたデータ基盤の設計 北島 祥伍 デジタルエンターテインメントオペレーションズ本部 事業戦略部 解析グループ

Slide 2

Slide 2 text

©MIXI 2 自己紹介 ● 北島 祥伍 ● 2019年新卒入社 ● モンスターストライク(以下、モンスト)など、デジタルエンターテインメン ト事業のデータエンジニアリング業

Slide 3

Slide 3 text

©MIXI 3   1. データ基盤とはなにか、その目的と設計 2. 共通・省力化のためのログ設計とBigQueryの連携 3. 共通化の成果とモンストへの還元

Slide 4

Slide 4 text

©MIXI 4 データ基盤とはなにか その目的と設計

Slide 5

Slide 5 text

©MIXI 5 データ基盤とは ● サービスに関するデータを集積するところ ○ 例) ユーザーの購買履歴や行動ログなど ○ テラバイトあるいはペタバイト級のデータウェアハウス(DWH) ● アプリケーションから定期的に(あるいはストリーミングで)データを取り 込む ● サービスの本番環境に影響を与えずに調査や分析ができる ○ もしデータ基盤がないと、本番のデータベースに直接クエリする必要 ○ 性能面でもDWHのほうが分析に向いている

Slide 6

Slide 6 text

©MIXI 6 モンストシリーズとデータ基盤 ● 2023年2月〜7月に5タイトルのゲームをモンストシリーズとしてリリー ス ○ ゲーム開発は開発会社と協業し、分析はMIXIが行うタイトルが多い ● 全タイトルが一定品質のデータ基盤を必要とする ● すべてを一から設計することは非効率 ● 従来のデータ基盤構築: ○ リリースは年に1回程度 ○ 従来は基礎から新システムを構築。全てを使い回すことは少ない ○ 今回はまとめて作りたい

Slide 7

Slide 7 text

©MIXI 7 なぜ毎回データ基盤を再設計しているのか ● 新しい技術のキャッチアップのため ○ 既存システムへの新技術導入は複雑な調整が必要 ● データエンジニアリング人材の育成のため ○ ゼロからデータ基盤を作る体験は成長を促す ● 様々なシステムのデータ基盤が混在し、管理コストが増大する問題は ある ● 多様な経験を通して、優れたデータ基盤について思いを馳せる

Slide 8

Slide 8 text

©MIXI 8 データ分析のための役割分担 ● ゲームサーバーからログを出力し、S3にファイルを置く ○ ゲーム開発側のサーバーエンジニアが行う ○ 標準インフラ構成を設けながらも、個々事案に柔軟に対応 ■ 詳細は「モンストシリーズでのデータ分析戦略(白川 2023)」を参照 ● S3上のファイルをBigQueryに取り込み、分析で使える状態まで加工 する ○ データエンジニアが行う ← 我々 ● ログを設計し、出力されたログを用いてBigQuery上で分析する ○ アナリストが行う

Slide 9

Slide 9 text

©MIXI 9 データ基盤の構成 ● ログデータに分析に必要な情報を乗せる ● ログをBigQueryに取り込む(下図構成) ● データベーススナップショットは使わない ○ 一部タイトルでは例外的に使用 ● マスターデータは別途取り込む Kinesis Agent 又は Fluentd S3 Bucket Cloud Storage BigQuery Looker AWS (ゲーム基盤) Google Cloud (データ基盤) 今日は主に こちらの話

Slide 10

Slide 10 text

©MIXI 10 共通・省力化のためのログ設計と BigQueryの連携

Slide 11

Slide 11 text

©MIXI 11 アナリストによるログ設計 ● 多くのゲームに共通するログは共通化 ● タイトル個別の機能に関するログを追加で設計 ● ログフォーマットを記載するスプレッドシートをデータエンジニアで用意 ○ ログフォーマット設計書の仕様をデータエンジニア側で設計することで効率化 を画策

Slide 12

Slide 12 text

©MIXI 12 BigQueryにおけるログの参照 ● 全てのログは一つのテーブルに集約する ● 日付ごとにパーティション化、ログタイプごとにクラスタ化、中身はJSON型 ● 各タイプのログはビューで参照する ログテーブル(app_log) {“type”: “log_user_create”, …} {“type”: “log_game_start“, …} {“type”: “log_user_create”, …} {“type”: “log_game_end“, …} {“type”: “log_gacha_play“, …} {“type”: “log_gacha_play“, …} {“type”: “log_user_create“, …} CREATE VIEW log_user_create AS SELECT * FROM app_log WHERE type = “log_user_create”; ユーザー登録ビュー {“type”: “log_user_create”, …} {“type”: “log_user_create”, …} {“type”: “log_user_create“, …}

Slide 13

Slide 13 text

©MIXI 13 JSON型にはビューを用意してあげたい ● ログのpayloadの構造はログタイプによって異なるためJSON型を採 用 ● JSON型はそのままでは扱いにくい ○ どのようなカラムがあるのかの情報がメタデータとして存在しない ○ アクセスするときのSQLクエリが少し長い JSONだけではpayloadの中身の構造 がわからない SELECT SAFE.INT64(payload.score) AS score FROM app_log WHERE type = “log_game_end” 使う時はSAFE.INT64 関数で JSON 型の整数型を普通の整数型にキャスト

Slide 14

Slide 14 text

©MIXI 14 JSON型をSTRUCT型にしてわかりやすく ● 右下のようなクエリで実現 ○ 詳細は「BigQueryのJSON型をSTRUCT型に変換する - Qiita(北島 2022)」 ○ 数十種類のログに対して毎回このようなクエリを書きたくないので自動生成する ログテーブル(app_log) {“type”: “log_game_start”, “user_id” : 394, “time”: “2024-01-01 23:59:59”, “payload”: { “stage_id”: 1000, “score”: 4567, “players”: [123, 456, 7890] }} CREATE VIEW log_game_start AS SELECT user_id, time, SAFE.INT64(payload.stage_id) AS stage_id, SAFE.INT64(payload.score) AS score, ARRAY(SELECT SAFE.INT64(player) FROM UNNEST(JSON_QUERY_ARRAY(payload.players)) player WITH OFFSET player_index ORDER BY player_index) AS players FROM app_log WHERE type = “log_game_start”;

Slide 15

Slide 15 text

©MIXI 15 ビューの定義が大変なので自動生成する ● スプレッドシートの書き方をきっちり定め、GASで自動生成 CREATE VIEW log_game_start AS SELECT SAFE.INT64(payload.stage_id) AS stage_id, SAFE.INT64(payload.score) AS score, ARRAY(SELECT SAFE.INT64(players) FROM UNNEST(JSON_QUERY_ARRAY(payload.players)) players WITH OFFSET players_index ORDER BY players_index) AS players FROM app_log WHERE type = “log_game_start”;

Slide 16

Slide 16 text

©MIXI 16 アナリストはわかりやすいテーブルを使える

Slide 17

Slide 17 text

©MIXI 17 ログフォーマット設計書について ● 非技術職でも広くログ設計に関われるようにスプレッドシートを採用 ● クエリなどの自動生成では一旦JSONに変換して処理している

Slide 18

Slide 18 text

©MIXI 18 スプレッドシートの採用の良し悪し メリット ● JSONの構造をGASでインタラ クティブに確認できる ● 使い慣れている人が多い ● GoogleWorkspaceの枠組み で共有が容易 ● GASとNode.js環境で関数を 共用できる デメリット ● GoogleWorkspace不採用の 開発会社とのやりとりが面倒 ● 自由度が高いために気づくと 壊れている ● エンジニア中心ならばYAMLな どをGitHubでやり取りしたほう が早い

Slide 19

Slide 19 text

©MIXI 19 共通化の成果とモンストへの還元

Slide 20

Slide 20 text

©MIXI 20 どれくらい共通化できたのか 共通化に成功 ● ログフォーマット設計書 ● データフロー ⇓ ● 全てほぼ同様のアーキテク チャで構成 ● IaCなのでコピペで構築 ● SQLもログフォーマット設計書 からコピペするだけ 共通化を断念 ● マスターデータの取得 ○ 開発会社ごとに異なる管理方法。開発 への影響が少ないよう柔軟に対応した 結果共通化はできず ● 細かい仕様 ○ 避けられない仕様や実装ミスなどによ り、どうしても少しずつ違ってしまう ○ 無理に開発側で合わせてもらうよりは、 データ基盤側で吸収するほうが楽なこと が多い(目的は省力化)

Slide 21

Slide 21 text

©MIXI 21 モンストデータ基盤に活かされていること ● 「巨大なJSON型のテーブル+ビュー」の仕組みはモンストにも還元 ● HTTPリクエストを記録するテーブルの効率化に採用 ○ 日付ごとにパーティション ○ APIエンドポイントごとにクラスタ化 ○ リクエストボディはJSON型で記録 ○ APIエンドポイントごとにビューを作成 ○ ビューはYAMLから自動生成 ● 従来はAPIエンドポイントごとにテーブルを作成しており、変更コストが 大きかった

Slide 22

Slide 22 text

©MIXI 22 まとめ ● ログ設計書のフォーマットを定めることで、データ基盤構築の省力化が できた ● クラスタキー、JSON型及びビューをうまく活用することで、運用が簡単 に ● モンストシリーズでの新しい取り組みが、モンストのデータ基盤も改善

Slide 23

Slide 23 text

©MIXI