Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
食べログのモジュラモノリス化戦略
Search
Tomoki Kuriyama
August 01, 2024
Programming
8
3.9k
食べログのモジュラモノリス化戦略
「10年超えRails開発の振り返りと未来 - 持続可能な開発の具体策」の発表資料です
https://pieceofcake.connpass.com/event/324722/
Tomoki Kuriyama
August 01, 2024
Tweet
Share
More Decks by Tomoki Kuriyama
See All by Tomoki Kuriyama
食べログのデッドコード解析基盤の裏側 - TECH Street Ruby勉強会
weakboson
0
140
緊急Ques 「食べログの品質ダッシュボード」-コードのメトリクスに基づくリファクタリング戦略
weakboson
0
21
Other Decks in Programming
See All in Programming
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
ふかぼれ!CSSセレクターモジュール / Fukabore! CSS Selectors Module
petamoriken
0
150
RubyLSPのマルチバイト文字対応
notfounds
0
120
Amazon Qを使ってIaCを触ろう!
maruto
0
400
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
120
Click-free releases & the making of a CLI app
oheyadam
2
110
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.7k
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
170
Remix on Hono on Cloudflare Workers
yusukebe
1
280
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
230
NSOutlineView何もわからん:( 前編 / I Don't Understand About NSOutlineView :( Pt. 1
usagimaru
0
330
現場で役立つモデリング 超入門
masuda220
PRO
15
3.2k
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
243
12k
The Language of Interfaces
destraynor
154
24k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
850
Statistics for Hackers
jakevdp
796
220k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
28
2k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Six Lessons from altMBA
skipperchong
27
3.5k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Transcript
食べログのモジュラモノリス化戦略 栗山 友樹 株式会社カカクコム 食べログ開発本部 技術部 マイクロサービス化チーム
発表者 自己紹介 栗山 友樹 (@weakboson) マイクロサービス化チームのここ数年の公開記事 株式会社カカクコム 食べログ開発本部 技術部 マイクロサービス化
チームリーダー兼テックリード 食べログのレストラン検索を支える Debezium と Apache Kafka – Qiita 食べログの内製Pub/Sub メッセージング基盤をApache Kafka にリプレイスした話 – Qiita 緊急Ques 「食べログの品質ダッシュボード」- コードのメトリクスに基づくリファクタリング戦略 Debezium Usecases in Tabelog - Tabelog Tech Blog 大規模サービスにマッチした可変レート分散トレーシング - Tabelog Tech Blog 食べログではサービス開発、DevOps などを経て2019 年からマイクロサービス化を担当し ています。趣味は居酒屋開拓とゲーム
食べログの紹介 日本最大級のレストラン検索・予約サービス レストランの口コミ、写真 レストランのネット予約 飲食店DX( 予約台帳、食べログオーダー、食べロ グ仕入) 月間総ページビュー:22 億2,293 万PV/
月 月間利用者数:9,350 万人/ 月 アクセス数(2024 年3 月現在) 主な機能
食べログではエンジニアを絶賛募集中です! 私達と一緒に日本最大級のグルメサービスを開発しませんか? 食べログでは多くのポジションでエンジニ アを募集中です。 ご興味のある方は、ぜひ採用サイトからご 連絡をください。エンジニア組織の文化風 土などを面接前に知りたい方は、本採用プ ロセス前にカジュアル面談も可能です。フ リーコメント欄に「カジュアル面談希望」 とご記載ください。ご応募お待ちしており
ます! モジュラモノリスアプリケーション化 エンジニア マイクロサービス化チーム エンジニアリングマネージャー候補 マイクロサービス基盤エンジニア
食べログマイクロサービス化の歴史 〜2019 年 マイクロサービス化に 振り回され期 2019 年〜 マイクロサービス化は 手段と悟り期 機能のAPI
化・システムの分割を目的としてしまった ある程度成功したが、結果的に大きな失敗もあった 「分散されたモノリス」アンチパターンになった 機能のAPI 化・システムの分割は手段と再認識 現状課題の可視化・分析 PoC とPDCA を繰り返し、失敗を小さく早めに済ませた
食べログマイクロサービス化の歴史 〜2019 年 マイクロサービス化に 振り回され期 2019 年〜 マイクロサービス化は 手段と悟り期 機能のAPI
化・システムの分割を目的としてしまった ある程度成功したが、結果的に大きな失敗もあった 「分散されたモノリス」アンチパターンになった 機能のAPI 化・システムの分割は手段と再認識 現状課題の可視化・分析 PoC とPDCA を繰り返し、失敗を小さく早めに済ませた
失敗事例: kiban システム - Before - レストランや口コミなどの食べログ主要機能を集約することを試みたシステム tabelog_base サブシステムA サブシステムB
共有ライブラリ レストラン 機能B レストラン 機能A レストラン 機能C メインDB レストランや口コミの機能も サブシステムと共有ライブラリに分散 サブシステムB で利用される機能が 共有ライブラリではなくサブシステムB の Controller に実装されることがよくあった
tabelog_base サブシステムA サブシステムB 共有ライブラリ レストラン 機能B レストラン 機能A レストラン 機能C
メインDB kiban システム レストラン 機能B レストラン 機能A レストラン 機能C 口コミ 機能B 口コミ 機能A 口コミ 機能C レビュアー 機能B レビュアー 機能A レビュアー 機能C 失敗事例: kiban システムの目指した姿 食べログの主要機能を全て分割しtabelog_base から主要機能のロジックを消す
tabelog_base サブシステムA サブシステムB 共有ライブラリ レストラン 機能B レストラン 機能A 機能Z メインDB
kiban システム レストラン 機能C 口コミ 機能C レビュアー 機能C 機能Y 機能X レストラン機能A,B は他の機能との依存関係が複雑 分離前の整理が困難で時間が必要だった レストランのような主要機能すべてのトラフィックを捌けるイン フラをtabelog_base と別に設けることができなかった 失敗事例: kiban システム - After - レストランの機能がtabelog_base とkiban に分かれた状態になってしまった
失敗事例: kiban システム - After - サービス間の過度な密結合が引き起こす問題はコードの重複が起こす問題よりも悪質 「分散されたモノリス」アンチパターン tabelog_base サブシステムA
サブシステムB 共有ライブラリ kiban システム 共有ライブラリの" 機能α" をDB を共有するAPI として切 り出したのだが、サブシステムA は共有ライブラリからA PI に切り替えができず、分散されたモノリスになってし まった。 1 2 出典: 分散されたモノリスになってしまうマイクロサービス - InfoQ ① ある機能が複数のリポジトリをまたいで成立している ② 共有DB のメンテナンスが煩雑 ドメイン境界が正しく切り分けられていないことで、 複数リポジトリのメンテナンスが必要になってしまった 過渡期限定の予定が長期化... 。テーブルの所有権が 不明瞭で、ALTER で障害を起こすリスク 具体的に起こった課題 機能α ライブラリ メインDB 機能α API
食べログマイクロサービス化の歴史 〜2019 年 マイクロサービス化に 振り回され期 2019 年〜 マイクロサービス化は 手段と悟り期 機能のAPI
化・システムの分割を目的としてしまった ある程度成功したが、結果的に大きな失敗もあった 「分散されたモノリス」アンチパターンになった 機能のAPI 化・システムの分割は手段と再認識 現状課題の可視化・分析 PoC とPDCA を繰り返し、失敗を小さく早めに済ませた
大規模なレガシーシステムを段階的に改善していく取り組み Qiita 「食べログの大規模なレガシーシステムを段階的に改善していく取り組み」に詳細記載 Step.1 システムの変更容易性 と変更安全性を高める Step.2 モノリスのレポジトリ を小さく速く改善する Step.3
マイクロサービス分割 食べログのシステム全体をモダンなインフ ラ基盤に刷新することで変更安全性と変更 容易性を高める 設計変更や不要なコード削除などの大胆な 改修を小さく速く繰り返し、疎結合・高凝 集なモノリスに作り変える 組織構造やビジネスファンクション・ドメイ ンモデル・ユースケース等々より、マイクロ サービスの境界を考察、定義し分割する 定時デプロイ制の廃止 カナリアリリース Blue/Green デプロイログやメトリクスの見える化 自動テストの整備 依存関係の分離 インターフェースの統一 コンポーネント化 Multi- Sided Platforms において( 真の意味で) マイクロサービス化はど うあるべきか?
ドメインの関心事 競争優位性 予約ビジネス拡大の速度を最大 化したい 事業の目標達成を競合他社以上 のペースで実現したい ビジネス要件の変化への対応 テスト容易性 変更容易性 モジュール性(
モジュール の凝集度、成熟度など) アーキテクチャ特性 ToBe = マイクロサービス ★★★★★ ★★★★★ アジリティ ★★★ ★★★★★ 全体的なコスト ★ シンプルさ ★ Next Stage = モジュラモノリス ★★★ As- Is ★ ★ ★★★ ★★★ ★ ★★ ★ ★★ ★ ★★ ★★ 最も重視 まあまあ重視 下がるのやむなし( トレードオフ) 凡例 食べログのAs- Is とToBe テスト容易性と変更容易性にフォーカスして 取り組むことにした
モデル(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 ① ビジネスロジックのテストにDB が必要で、有効なデー タの用意が難しい ②
ビジネスロジックから外部(API など) に直接依存している * 良い単体テストを構成する4 本の柱 リファクタリングへの耐性 保守のしやすさ 退行に対する保護 迅速なフィードバック API など テスト容易性のAs- Is 自動テストのカバレッジと品質(*) を上げるのが難しい 1 2 出典: 単体テストの考え方/ 使い方 - 第4 章
ドメイン層 アプリケーション層 永続化層(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 ① ビジネスロジックとDB 入出力を分離する
② 外部に直接依存しないようにする API など 1 テスト容易性のNext Stage ビジネスロジックが単体でテストできる= テスト容易性が 向上する 2
卓 営業設定 コース 予約 カード 決済 他サービス 連携 ポイント業 務
① コアドメインから非コアドメイン方向に依存がある ② 依存が循環している ③ 別のドメインのロジックが混入している ④ ドメイン同士の境界が不明瞭 他サービス 連携 変更容易性のAs- Is 非コアドメイン改修の際にコアドメインで不具合が生じ るもらい事故が多い コアドメイン 非コアドメイン 1 2 3 4 良くない部分
① コアドメインから非コアドメインに依存しない ② 依存を一方向に整理 ③ 異なるドメインのロジックを混入させない ④ ドメイン同士の境界を明瞭にする 卓 営業設定
コース 予約 カード 決済 他サービス 連携 ポイント業 務 変更容易性のNext Stage 非コアドメイン改修に際してコアドメインへの影響はな い 1 2 3 4 コアドメイン 非コアドメイン
1. システム的な責務 2. ドメイン As- Is Next Stage = モジュラモノリス
中間まとめ: 食べログモジュラモノリスの2 軸 卓 営業設定 コース 予約 カード 決済 他サービス 連携 ポイント業 務 他サービス 連携 卓 営業設定 コース 予約 カード 決済 他サービス 連携 ポイント業 務 モデル(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 API など ドメイン層 アプリケーション層 永続化層(ActiveRecord) 外部入力のバリデーション ビジネスロジック DB への保存・参照 API など
アウトカム 時間 過渡期が辛いだけの改善は開発チームに受け入れられず成功しないので、 開発チームが早期に大きなアウトカムを享受できる戦略を立てる。 早期に大きなアウトカムを出す戦略 各ドメインを1 つずつモジュラモノリス化( 赤) 効果的な戦略 複数ドメインに横断的な課題を1
つずつ解決( 青) 完了したドメインが少ない序盤はアウトカムを享受 できる機能が少なく改善が小さい 最初にインパクトの大きい横断的課題を解決 次にコアドメインからモジュラモノリス化 1. 2. 序盤からシステム全体に大きな改善
横断的課題のスコアリング ICE スコアリング Impact( 影響): コード量、更新頻度、リバート回数など Confidence( 確実さ): ( 差異がわからなかったので固定)
Ease( 容易さ): 結合している他ドメインの数など 外部API 依存が最高スコア 横断的課題の中でもこれからはじめる Excel で 横断的課題の ICE スコアを計算
予約モデル 提携先連携 ロジック 予約 ビジネス ロジック 予約登録 コントローラ Use 提携先API
HTTP Use 予約登録の際に提携先に情報連携する機能の概略図 コアドメイン 非コアドメイン 外部API 依存引き剥がし - Before 変更容易性を低下させる要因 テスト容易性を低下させる要因 コアドメインから非コアドメイン方向 に依存がある 予約( コアドメイン) から提携先連携( 非コア ドメイン) 方向への依存がある ビジネスロジックから外部(API など) に 直接依存している
ドメインイベントの概念を導入 予約モデル( コアドメイン) は予約登録が 成立したドメインイベントオブジェクト をcreate するだけ 予約モデル 予約 ビジネス
ロジック 予約登録 コントローラ Use 予約登録 ドメイン イベント <<create>> { "before": nil "after": { "booking_id":"net:123", "visit_member":4, ... } } ドメインイベントは予約ドメインが他の ドメインに公開してもよい情報だけを持 つJSON のようなオブジェクト 外部API 依存引き剥がし - ドメインイベントの導入
予約モデル 予約 ビジネス ロジック 予約登録 コントローラ Use 提携先API 提携先連携 ロジック
予約登録 ドメイン イベント <<create>> Use HTTP { "before": nil "after": { "booking_id":"net:123", "visit_member":4, ... } } Use 外部API 依存引き剥がし - After 変更容易性を低下させる要因 テスト容易性を低下させる要因 コアドメインから非コアドメイン方向 に依存がある 提携先連携はドメインイベントをUse して 提携先API にリクエストする。 (Pub/Sub パターンを同期処理するイメー ジ) ビジネスロジックから外部(API など) へ 直接依存している → 解消 → 解消
入出力の組み合わせテストの容易性 before after モックデータ数 (FactoryBot で生成するオブジェクト) 数 多い 提携先連携ドメインだけで 7
個必要 少ない 提携先連携ドメインでは 2 個に削減 困難 FactoryBot の組み合わせは 準備が煩雑 容易 ドメインイベントの組み合わ せは準備が容易 実行時間 ( ハッピーパス1 つを100 回実行した計測値) 長い 5.55 sec 短い 3.15 sec リファクタリングによるテストの壊れやすさ 壊れやすい 予約の内部実装が変わると 壊れやすい 壊れにくい 予約の内部実装が変わっても イベントに変化がなければ壊 れない 要素 外部API 依存引き剥がし - テスト容易性の Before/After
食べログのモジュラモノリス化戦略概要 〜2024 年9 月 2024 年10 月〜 横断的課題の解決 ドメインそれぞれの解決 ドメインの境界を明確にする
システム的な責務の分離 ドメインの依存関係を整理する 卓、営業設定、コース、etc... DB I/O をドメインモデルと分離 Pub/Sub パターンにより依存を疎結合にする 大きすぎるドメインモデルを分割する 外部依存の引き剥がし 他ドメイン依存の引き剥がし 提携先API 通知( メール・FAX ・ アプリPUSH ・電話) etc...
食べログではかつてマイクロサービス化自体を目的としてやや失敗した。現 在はテスト容易性・変更容易性を得る手段と考えている コアドメインの1 つである予約はモジュラモノリスを経由してマイクロサー ビスにする計画である。予約以外はモジュラモノリスで充分なドメインもあ るだろう システム的な責務とドメインの2 軸でモジュラモノリス化することにした 早期にアウトカムが享受できるよう横断的課題の解決からはじめ、その後ド メインそれぞれの課題を解決していく戦略を立てた
横断的な課題の1 つである外部API 依存引き剥がしを実施中、テスト容易性に ついて定量的な成果が出せている まとめ