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

食べログのモジュラモノリス化戦略

 食べログのモジュラモノリス化戦略

「10年超えRails開発の振り返りと未来 - 持続可能な開発の具体策」の発表資料です
https://pieceofcake.connpass.com/event/324722/

Tomoki Kuriyama

August 01, 2024
Tweet

More Decks by Tomoki Kuriyama

Other Decks in Programming

Transcript

  1. 発表者 自己紹介 栗山 友樹 (@weakboson) マイクロサービス化チームのここ数年の公開記事 株式会社カカクコム 食べログ開発本部 技術部 マイクロサービス化

    チームリーダー兼テックリード 食べログのレストラン検索を支える Debezium と Apache Kafka – Qiita 食べログの内製Pub/Sub メッセージング基盤をApache Kafka にリプレイスした話 – Qiita 緊急Ques 「食べログの品質ダッシュボード」-​ コードのメトリクスに基づくリファクタリング戦略 Debezium Usecases in Tabelog -​ Tabelog Tech Blog 大規模サービスにマッチした可変レート分散トレーシング -​ Tabelog Tech Blog 食べログではサービス開発、DevOps などを経て2019 年からマイクロサービス化を担当し ています。趣味は居酒屋開拓とゲーム
  2. 食べログマイクロサービス化の歴史 〜2019 年 マイクロサービス化に 振り回され期 2019 年〜 マイクロサービス化は 手段と悟り期 機能のAPI

    化・システムの分割を目的としてしまった ある程度成功したが、結果的に大きな失敗もあった 「分散されたモノリス」アンチパターンになった 機能のAPI 化・システムの分割は手段と再認識 現状課題の可視化・分析 PoC とPDCA を繰り返し、失敗を小さく早めに済ませた
  3. 食べログマイクロサービス化の歴史 〜2019 年 マイクロサービス化に 振り回され期 2019 年〜 マイクロサービス化は 手段と悟り期 機能のAPI

    化・システムの分割を目的としてしまった ある程度成功したが、結果的に大きな失敗もあった 「分散されたモノリス」アンチパターンになった 機能のAPI 化・システムの分割は手段と再認識 現状課題の可視化・分析 PoC とPDCA を繰り返し、失敗を小さく早めに済ませた
  4. 失敗事例: kiban システム - Before - レストランや口コミなどの食べログ主要機能を集約することを試みたシステム tabelog_base サブシステムA サブシステムB

    共有ライブラリ レストラン 機能B レストラン 機能A レストラン 機能C メインDB レストランや口コミの機能も サブシステムと共有ライブラリに分散 サブシステムB で利用される機能が 共有ライブラリではなくサブシステムB の Controller に実装されることがよくあった
  5. tabelog_base サブシステムA サブシステムB 共有ライブラリ レストラン 機能B レストラン 機能A レストラン 機能C

    メインDB kiban システム レストラン 機能B レストラン 機能A レストラン 機能C 口コミ 機能B 口コミ 機能A 口コミ 機能C レビュアー 機能B レビュアー 機能A レビュアー 機能C 失敗事例: kiban システムの目指した姿 食べログの主要機能を全て分割しtabelog_base から主要機能のロジックを消す
  6. tabelog_base サブシステムA サブシステムB 共有ライブラリ レストラン 機能B レストラン 機能A 機能Z メインDB

    kiban システム レストラン 機能C 口コミ 機能C レビュアー 機能C 機能Y 機能X レストラン機能A,B は他の機能との依存関係が複雑 分離前の整理が困難で時間が必要だった レストランのような主要機能すべてのトラフィックを捌けるイン フラをtabelog_base と別に設けることができなかった 失敗事例: kiban システム - After - レストランの機能がtabelog_base とkiban に分かれた状態になってしまった
  7. 失敗事例: kiban システム - After - サービス間の過度な密結合が引き起こす問題はコードの重複が起こす問題よりも悪質 「分散されたモノリス」アンチパターン tabelog_base サブシステムA

    サブシステムB 共有ライブラリ kiban システム 共有ライブラリの" 機能α" をDB を共有するAPI として切 り出したのだが、サブシステムA は共有ライブラリからA PI に切り替えができず、分散されたモノリスになってし まった。 1 2 出典: 分散されたモノリスになってしまうマイクロサービス -​ InfoQ ① ある機能が複数のリポジトリをまたいで成立している ② 共有DB のメンテナンスが煩雑 ドメイン境界が正しく切り分けられていないことで、 複数リポジトリのメンテナンスが必要になってしまった 過渡期限定の予定が長期化... 。テーブルの所有権が 不明瞭で、ALTER で障害を起こすリスク 具体的に起こった課題 機能α ライブラリ メインDB 機能α API
  8. 食べログマイクロサービス化の歴史 〜2019 年 マイクロサービス化に 振り回され期 2019 年〜 マイクロサービス化は 手段と悟り期 機能のAPI

    化・システムの分割を目的としてしまった ある程度成功したが、結果的に大きな失敗もあった 「分散されたモノリス」アンチパターンになった 機能のAPI 化・システムの分割は手段と再認識 現状課題の可視化・分析 PoC とPDCA を繰り返し、失敗を小さく早めに済ませた
  9. 大規模なレガシーシステムを段階的に改善していく取り組み Qiita 「食べログの大規模なレガシーシステムを段階的に改善していく取り組み」に詳細記載 Step.1 システムの変更容易性 と変更安全性を高める Step.2 モノリスのレポジトリ を小さく速く改善する Step.3

    マイクロサービス分割 食べログのシステム全体をモダンなインフ ラ基盤に刷新することで変更安全性と変更 容易性を高める 設計変更や不要なコード削除などの大胆な 改修を小さく速く繰り返し、疎結合・高凝 集なモノリスに作り変える 組織構造やビジネスファンクション・ドメイ ンモデル・ユースケース等々より、マイクロ サービスの境界を考察、定義し分割する 定時デプロイ制の廃止 カナリアリリース Blue/Green デプロイログやメトリクスの見える化 自動テストの整備 依存関係の分離 インターフェースの統一 コンポーネント化 Multi-​ Sided Platforms において( 真の意味で) マイクロサービス化はど うあるべきか?
  10. ドメインの関心事 競争優位性 予約ビジネス拡大の速度を最大 化したい 事業の目標達成を競合他社以上 のペースで実現したい ビジネス要件の変化への対応 テスト容易性 変更容易性 モジュール性(

    モジュール の凝集度、成熟度など) アーキテクチャ特性 ToBe = マイクロサービス ★★★★★ ★★★★★ アジリティ ★★★ ★★★★★ 全体的なコスト ★ シンプルさ ★ Next Stage = モジュラモノリス ★★★ As-​ Is ★ ★ ★★★ ★★★ ★ ★★ ★ ★★ ★ ★★ ★★ 最も重視 まあまあ重視 下がるのやむなし( トレードオフ) 凡例 食べログのAs-​ Is とToBe テスト容易性と変更容易性にフォーカスして 取り組むことにした
  11. モデル(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 ① ビジネスロジックのテストにDB が必要で、有効なデー タの用意が難しい ②

    ビジネスロジックから外部(API など) に直接依存している * 良い単体テストを構成する4 本の柱 リファクタリングへの耐性 保守のしやすさ 退行に対する保護 迅速なフィードバック API など テスト容易性のAs-​ Is 自動テストのカバレッジと品質(*) を上げるのが難しい 1 2 出典: 単体テストの考え方/ 使い方 -​ 第4 章
  12. ドメイン層 アプリケーション層 永続化層(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 ① ビジネスロジックとDB 入出力を分離する

    ② 外部に直接依存しないようにする API など 1 テスト容易性のNext Stage ビジネスロジックが単体でテストできる= テスト容易性が 向上する 2
  13. 卓 営業設定 コース 予約 カード 決済 他サービス 連携 ポイント業 務

    ① コアドメインから非コアドメイン方向に依存がある ② 依存が循環している ③ 別のドメインのロジックが混入している ④ ドメイン同士の境界が不明瞭 他サービス 連携 変更容易性のAs-​ Is 非コアドメイン改修の際にコアドメインで不具合が生じ るもらい事故が多い コアドメイン 非コアドメイン 1 2 3 4 良くない部分
  14. ① コアドメインから非コアドメインに依存しない ② 依存を一方向に整理 ③ 異なるドメインのロジックを混入させない ④ ドメイン同士の境界を明瞭にする 卓 営業設定

    コース 予約 カード 決済 他サービス 連携 ポイント業 務 変更容易性のNext Stage 非コアドメイン改修に際してコアドメインへの影響はな い 1 2 3 4 コアドメイン 非コアドメイン
  15. 1. システム的な責務 2. ドメイン As-​ Is Next Stage = モジュラモノリス

    中間まとめ: 食べログモジュラモノリスの2 軸 卓 営業設定 コース 予約 カード 決済 他サービス 連携 ポイント業 務 他サービス 連携 卓 営業設定 コース 予約 カード 決済 他サービス 連携 ポイント業 務 モデル(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 API など ドメイン層 アプリケーション層 永続化層(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 API など
  16. アウトカム 時間 過渡期が辛いだけの改善は開発チームに受け入れられず成功しないので、 開発チームが早期に大きなアウトカムを享受できる戦略を立てる。 早期に大きなアウトカムを出す戦略 各ドメインを1 つずつモジュラモノリス化( 赤) 効果的な戦略 複数ドメインに横断的な課題を1

    つずつ解決( 青) 完了したドメインが少ない序盤はアウトカムを享受 できる機能が少なく改善が小さい 最初にインパクトの大きい横断的課題を解決 次にコアドメインからモジュラモノリス化 1. 2. 序盤からシステム全体に大きな改善
  17. 横断的課題のスコアリング ICE スコアリング Impact( 影響): コード量、更新頻度、リバート回数など Confidence( 確実さ): ( 差異がわからなかったので固定)

    Ease( 容易さ): 結合している他ドメインの数など 外部API 依存が最高スコア 横断的課題の中でもこれからはじめる Excel で 横断的課題の ICE スコアを計算
  18. 予約モデル 提携先連携 ロジック 予約 ビジネス ロジック 予約登録 コントローラ Use 提携先API

    HTTP Use 予約登録の際に提携先に情報連携する機能の概略図 コアドメイン 非コアドメイン 外部API 依存引き剥がし - Before 変更容易性を低下させる要因 テスト容易性を低下させる要因 コアドメインから非コアドメイン方向 に依存がある 予約( コアドメイン) から提携先連携( 非コア ドメイン) 方向への依存がある ビジネスロジックから外部(API など) に 直接依存している
  19. ドメインイベントの概念を導入 予約モデル( コアドメイン) は予約登録が 成立したドメインイベントオブジェクト をcreate するだけ 予約モデル 予約 ビジネス

    ロジック 予約登録 コントローラ Use 予約登録 ドメイン イベント <<create>> { "before": nil "after": { "booking_id":"net:123", "visit_member":4, ... } } ドメインイベントは予約ドメインが他の ドメインに公開してもよい情報だけを持 つJSON のようなオブジェクト 外部API 依存引き剥がし - ドメインイベントの導入
  20. 予約モデル 予約 ビジネス ロジック 予約登録 コントローラ Use 提携先API 提携先連携 ロジック

    予約登録 ドメイン イベント <<create>> Use HTTP { "before": nil "after": { "booking_id":"net:123", "visit_member":4, ... } } Use 外部API 依存引き剥がし - After 変更容易性を低下させる要因 テスト容易性を低下させる要因 コアドメインから非コアドメイン方向 に依存がある 提携先連携はドメインイベントをUse して 提携先API にリクエストする。 (Pub/Sub パターンを同期処理するイメー ジ) ビジネスロジックから外部(API など) へ 直接依存している → 解消 → 解消
  21. 入出力の組み合わせテストの容易性 before after モックデータ数 (FactoryBot で生成するオブジェクト) 数 多い 提携先連携ドメインだけで 7

    個必要 少ない 提携先連携ドメインでは 2 個に削減 困難 FactoryBot の組み合わせは 準備が煩雑 容易 ドメインイベントの組み合わ せは準備が容易 実行時間 ( ハッピーパス1 つを100 回実行した計測値) 長い 5.55 sec 短い 3.15 sec リファクタリングによるテストの壊れやすさ 壊れやすい 予約の内部実装が変わると 壊れやすい 壊れにくい 予約の内部実装が変わっても イベントに変化がなければ壊 れない 要素 外部API 依存引き剥がし - テスト容易性の Before/After
  22. 食べログのモジュラモノリス化戦略概要 〜2024 年9 月 2024 年10 月〜 横断的課題の解決 ドメインそれぞれの解決 ドメインの境界を明確にする

    システム的な責務の分離 ドメインの依存関係を整理する 卓、営業設定、コース、etc... DB I/O をドメインモデルと分離 Pub/Sub パターンにより依存を疎結合にする 大きすぎるドメインモデルを分割する 外部依存の引き剥がし 他ドメイン依存の引き剥がし 提携先API 通知( メール・FAX ・ アプリPUSH ・電話) etc...