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

digdag中心の生活

Rikiya Oguchi
September 30, 2019

 digdag中心の生活

Rikiya Oguchi

September 30, 2019
Tweet

Other Decks in Technology

Transcript

  1. 小口 力也 Rikiya Oguchi 2017 1st half - 2nd half

    • 電機メーカーに新卒入社 • IT 部門で社内システムの企画・開発に従事 2018 1st half - • DeNA に JOIN ◦ BQ 警察(コスト最適化) ◦ ゲーム分析の ETL 設計・開発 ◦ データエンジニア組織の立ち上げ ◦ オープンデータの収集 ◦ ML Ops • 副業 ◦ スポットバイトのマッチングアプリ 「Spotmate」の分析基盤の立ち上げ 自己紹介 2
  2. 2011 - 2015 • 全社横断組織としてデータ分析組織が誕生 • 様々な事業の分析を担当 2016 - 2018

    • ゲーム事業の分析組織が独立 • 他の事業部にもそれぞれ分析担当が所属 2019 - • 分析のエンジニア機能に特化した Gr として データエンジニアリング Gr が2月に発足 • ゲーム以外の横断分析組織として分析推進部 も発足 DeNA分析部の紹介 3 ゲーム スポーツ オート モーティブ ヘルスケア エンターテイ ンメント
  3. 役割 • ゲーム事業における意思決定支援 ◦ ゲーム内外の施策の振り返り ◦ 事業戦略立案サポート          メンバー •

    データエンジニア(6名): 分析の効率化・高度化 • データアナリスト(22名): 担当ゲームの意思決定支援 • データサイエンティスト(2名): 高度な分析手法の探求 • ゲームメカニクスのデザイナー(8名): ゲーム内の UX・経済設計 DeNA分析部の紹介 4
  4. 事業系 • アナリストの意思決定支援のサポート • 新規技術の獲得(Looker の PoC など) • クラウド移行(全社戦略)    

    保守系 • リファクタリング • 運用設計・手順化 改善系 • ML Ops • コスト最適化(BQ 警察) ◦ 【参考】Google Cloud Next Tokyo 2019 岩尾 一優/エルアズハリ ムラド 「BigQuery を使い倒せ! DeNA データエンジニアの取り組み事例」 https://cloud.withgoogle.com/next/tokyo/sessions?session=D2-2-S09 データエンジニアの役割 5
  5. 8

  6. 9

  7. 10

  8. 11

  9. 12

  10. 13

  11. 14

  12. 15

  13. Medjed (内製バルクロードツール) ゲーム事業部の分析基盤(入社当時) 20 Log Collector Hadoop Vertica Argus(内製BI) App

    Server DB BigQuery gsec (Linux Server) Jenkins Hue log Service 分析基盤 GCP • 大規模データはオンプレミスの Hadoop に格納していた。 • データマートはオンプレの Vertica 上で行ってきたが、運用のしやすさ /機械学習を用いた分析の発展という観点から   GCPの高機能DBであるBigQuery への移行を進めてきた。 • アドホックな分析作業は Linux サーバに ssh でログインして実行。 • スケジュールバッチは Linux サーバ上で稼働する Jenkins で実行。 • HadoopからVertica/BQへのロードは内製のバルクロードツール medjedを使ってWebUIで設定しロードしていた
  14. GCP Project A GCP Project X GKE Service A ゲーム事業部の分析基盤(クラウド移行後)

    21 21 • 分析基盤を全て GCP 上に構築し、サービス毎に GCP プロジェクトを分ける。 • ログ / DB スナップショットは Google Cloud Storage に格納する(データレイク)。 • DWH / データマートは全て BQ へ移行する。 • アドホックな分析作業は BQ の Web UI、もしくは業務端末 ( mac /win )上の CLI で実行する。 • スケジュールバッチは digdag という OSS で実行する。digdag は GKE 上でコンテナとして実行する。 • 現在はクラウド移行中のため、新旧の環境が混在している状況 App Server DB log BigQuery digdag GCS Service B GCP Project B Service C GCP Project C Service ・・・ ・・・ 分析基盤 Argus(内製BI) Medjed (内製バルクロードツール)
  15. 28 過去のパイプライン Github:e EC2-Instance A Jenkins create_common Title A common_summary.sql

    unique_summary.sql Title A BigQuery git clone なぜかタイトル個別のリポジトリに タイトル横断で汎用的に利用できるソースコードが置かれている
  16. Github:e EC2-Instance A Jenkins create_common Title A common_summary.sql unique_summary.sql Title

    A BigQuery git clone Github:e EC2-Instance B Jenkins create_common Title B common_summary.sql unique_summary.sql Title B BigQuery git clone 過去のパイプライン 新規タイトルが立ち上がると便利なのでコピーされる でも、個別のリポジトリにコピーされている模様
  17. いつの間にか汎用的に使えたはずのソースコードが 亜種になり始める Github:e EC2-Instance A Jenkins create_common Title A common_summary_亜種

    unique_summary Title A BigQuery git clone Github:e EC2-Instance B Jenkins create_common Title B common_summary unique_summary Title B BigQuery git clone 過去のパイプライン
  18. こっちも闇落ちしちゃう Github:e EC2-Instance A Jenkins create_common Title A common_summary_亜種 unique_summary

    Title A BigQuery git clone Github:e EC2-Instance B Jenkins create_common Title B common_summary_亜種2 unique_summary Title B BigQuery git clone 過去のパイプライン
  19. 32

  20. 33

  21. 34

  22. JenkinsのGUIで設定という仕様上 ワークフローもGitでコード管理できておらず、 背景や意図がわからないことも Github:e EC2-Instance A Jenkins create_common Title A

    common_summary_亜種 unique_summary Title A BigQuery git clone Github:e EC2-Instance B Jenkins create_common Title B common_summary_亜種2 unique_summary Title B BigQuery git clone 過去のパイプライン
  23. 40 散らかる背景 • 工数不足 ◦ 全体最適でどうあるべきかを考える時間がない ▪ 新規タイトルがどんどんリリースされる ▪ 構築するパイプラインの数が多い

    ▪ アナリストがタイトル間で掛け持ちするケースが多くなる • 設計のバラつき ◦ 全体最適でアーキテクチャを取りまとめ・設計する役割が定まっていなかった ▪ 部のメンバー全員が全体最適でアーキテクチャを設計できるわけではない →インフラエンジニアとアナリストの間に立つ  データエンジニアリング Grが発足した背景でもあります
  24. 46

  25. 48 課題 • 辛かったこと①:コードが管理できていない ◦ 汎用的なソースコードがタイトル個別のリポジトリに管理されている ◦ せっかく汎用性があったのに独自進化してしまう • 辛かったこと②:ワークフローが管理できていない

    ◦ JenkinsのGUI設定の弊害で、ワークフローが Gitで管理できていない ◦ 必ず実行されなければならないジョブが、 あるタイトルではされていて、あるタイトルではされていないということがある  →後々また少ない工数を奪う (=技術的負債)
  26. 53 過去のパイプライン Github:e EC2-Instance A Jenkins create_common EC2-Instance B EC2-Instance

    C Title A common_summary unique_summary Title B common_summary unique_summary Title C common_summary unique_summary Title A Title B Title C BigQuery BigQuery BigQuery Jenkins create_common Jenkins create_common git clone
  27. 54 課題 • 辛かったこと①:コードが管理できていない ◦ 汎用的なソースコードがタイトル個別のリポジトリに管理されている ◦ せっかく汎用性があったのに独自進化してしまう • 辛かったこと②:ワークフローが管理できていない

    ◦ JenkinsのGUI設定の弊害で、ワークフローが Gitで管理できていない ◦ 必ず実行されなければならないジョブが、 あるタイトルではされていて、あるタイトルではされていないということがある
  28. VPC DeNA Office Digdag Metadata Cloud SQL Cloud IAP DeNA

    Development Infra Analytics Data BigQuery Service Analytics Environment Digdag Task Log Cloud Storage Cloud NAT Cloud Armor Cloud Load Balancing Digdag Kubernetes Engine Logs & DB Snapshots Cloud Storage Analytics Tools Argus(BI) Medjed (Bulk Load) Service Environment logs & DB Snapshots Common Analytics Environment Container Registry Cloud DNS Cloud Build digdagのインフラ構成 【参考】「自由と統制のバランス 共通分析基盤のアプローチ」 DeNA長谷川さん       (Data Pipeline Casual Talk Vol3 登壇資料)  https://speakerdeck.com/ryoji_hasegawa/zi-you-totong-zhi-falsebaransu-fen-xi-ji-pan-falseapuroti
  29. GKE 56 digdag以後のパイプライン Github:e pod Title A Title A summary.dig

    common_summary unique_summary Title B summary.dig common_summary unique_summary Title C summary.dig common_summary unique_summary BigQuery BigQuery BigQuery common common_summary submodule digdag push GKE pod Title B GKE pod Title C
  30. 58 設計のポイント① - submodule   dena/common common_summary ├access ├consume ├install

    └session dena/title_A summary.dig unique_summary  └battle    ├create_battle.dig    └create_battle.sql common_summary ├access │├create_access.dig │└create_access.sql ├consume ├install └session git submodule add • タイトル個別のリポジトリと共通用のリポジトリをサブモジュールで連携
  31. • 辛かったこと②:ワークフローが管理できていない ◦ digdag で YAML でワークフローをコード管理 ▪ Jenkins時代にはできていなかったワークフローをコード管理 ▪

    .digでワークフローの雛形を作成し、設計のバラつきをなくす ▪ サブモジュールで個別と共通リポジトリがシンクされているので digdag push だけで中間集計ジョブを作成可能な状態を実現 59 改善した課題②
  32. digdag push 60 設計のポイント② - digdag push dena/title_A common_summary ├access

    │├create_access.dig │└create_access.sql ├consume ├install └session summary.dig unique_summary  └battle    ├create_battle.dig    └create_battle.sql digdag pod dena/title_A common_summary ├access │├create_access.dig │└create_access.sql ├consume ├install └session summary.dig unique_summary  └battle    ├create_battle.dig    └create_battle.sql • digdag pushでgit cloneした内容をdigdag側にProjectとしてコピー
  33. 61 設計のポイント③ - 親dig・子dig summary.dig timezone: "Asia/Tokyo" schedule: daily>: 00:00:00

    # 共通で使う環境変数を読み込む !include : 'config/config.dig' # 共通集計(アクセスログの集計) +create_access: call>: 'common_summary/access/create_access.dig' # タイトル個別の集計(バトルログの集計) +create_battle: call>: 'unique_summary/battle/create_battle.dig' 親dig = 全体のワークフローを定義する dig 子dig = 処理の詳細を定義する dig →目次とコンテンツ的な関係性
  34. 62 設計のポイント③ - 子dig summary.dig timezone: "Asia/Tokyo" schedule: daily>: 00:00:00

    # 共通で使う環境変数を読み込む !include : 'config/config.dig' # 共通集計(アクセスログの集計) +create_access: call>: 'common_summary/access/create_access.dig' # タイトル個別の集計(バトルログの集計) +create_battle: call>: 'unique_summary/battle/create_battle.dig' create_access.dig +create_access: loop>: ${ moment(END_DATE).diff(moment(START_DATE), 'days') + 1 } _do: _export: DATE: ${ moment(START_DATE).add(i,'days').format("YYYY-MM-DD")} SUFFIX_DATE:${moment(START_DATE).add(i,'days').format("YYYYMMDD") } bq>: create_access.sql destination_table: access$${SUFFIX_DATE} dataset: summary write_disposition: WRITE_TRUNCATE ・再集計に耐えうるよう日付でループ処理する設計  →冪等性の担保 ・部の様々なメンバーが設置することも考慮し、  データセット名  テーブル名  クエリのファイル名  を入れ替えれば、基本的にどんな集計も実現できる設計にした
  35. 63 設計のポイント③ - config.dig summary.dig timezone: "Asia/Tokyo" schedule: daily>: 00:00:00

    # 共通で使う環境変数を読み込む !include : 'config/config.dig' # 共通集計(アクセスログの集計) +create_access: call>: 'common_summary/access/create_access.dig' # タイトル個別の集計(バトルログの集計) +create_battle: call>: 'unique_summary/battle/create_battle.dig' config.dig _export: START_DATE: ${ moment().subtract(1, 'day').format('YYYY-MM-DD') } END_DATE: ${ moment().subtract(1, 'day').format('YYYY-MM-DD') } _retry: limit: 1 interval: 600 interval_type: constant ・どの処理でも使用する実行対象日やリトライの詳細を _exportで定義して config.digとして、ワークフローの最初で実行 ・config.digを!includeで実行すれば配下全ての処理で使用可能
  36. GKE 64 digdag以後のパイプライン Github:e pod Title A Title A summary.dig

    common_summary unique_summary Title B summary.dig common_summary unique_summary Title C summary.dig common_summary unique_summary BigQuery BigQuery BigQuery common common_summary submodule digdag push GKE pod Title B GKE pod Title C
  37. 65 まとめ • 課題①:コードが管理できていない問題 ◦ Gitのサブモジュールを用いて再設計 ▪ 汎用性のあるソースコードはタイトル横断用のリポジトリに分離 ▪ タイトル個別のリポジトリと共通リポジトリをサブモジュールで連携

    • 課題②:ワークフローが管理できていない問題 ◦ digdag で YAML でワークフローをコード管理 ▪ Jenkins時代にはできていなかったワークフローをコード管理 ▪ コードでワークフローの雛形を作成し、設計のバラつきをなくす ▪ サブモジュールで個別と共通レポジトリがシンクされているので digdag push だけで中間集計ジョブを作成可能