マイクロサービス化による未来は本当にネガティブだけなのか? [FLEXY meetup イベントレポート]

7月26日 FLEXY meetup

2023年7月26日に開催されたFLEXY meetupのテーマは「マイクロサービス」です。
システム分割によるメリットを得ようと、機能やサービス単位のマイクロサービス化に挑戦した数多くの企業事例をこれまで耳にしました。
一方取り組んだ結果、難易度の高さから多くの功罪が発生しているのも事実です。
「マイクロサービスの実践がもたらす結果は本当に負の側面だけなのか?」
今回はマイクロサービスのメリット・デメリットをフラットに語るべくカカクコム社の栗山さん、ネットプロテクションズ社の春田さんをお招きし、実際に直面した課題や現在試みているシステム戦略などについて広く伺いました。

目次

登壇者

NP_haruta

春田 岬さん|株式会社ネットプロテクションズ ソリューションアーキテクトグループ兼BtoBディベロップメントグループ 統括責任者 @harumisa31

後払い決済の会社でフリーダムに活動するソリューションアーキテクト。
AWS移行や、IaCの導入、アーキテクチャ刷新、マルチアカウント化、マイクロサービス構築と色んなことをやっています。

taberog_kuriyama

栗山 友樹さん|株式会社カカクコム 食べログシステム本部 技術部 マイクロサービス化チームリーダー @weakboson

食とSNSが好きで、両方一緒に開発できる食べログにジョインした食い倒れITデベロッパ。
口コミ投稿フロントエンドから、レストラン検索バックエンド、インフラのIaC化まであちこちなんでも担当した後2019年から現チームでマイクロサービス化を進めている。

NP掛け払いにおけるマイクロサービス化実例

解決したい領域・マイクロサービス化した理由

春田氏:
当社がマイクロサービス化に挑戦した理由は3つあります。

  • 特定の決済プロダクトに依存しない横断的な取引先情報の管理を行いたい
  • 包括加盟など複雑な契約形態が出てきた場合に備えて横断的に利用し契約情報を管理できる状態を作りたい
  • 加盟審査の業務プロセスを一本化し機能を一本化させることで業務を効率化したい
といずれも事業都合の話が多いですね。

NP社 マイクロサービス化の理由

春田氏:
また、マイクロサービスのメリットとして追求したかったのは、合成可能性と組織の自律性の2点です。

NP社 マイクロサービス化で追求したいこと

システム構成図

春田氏:
当社がドメインをどう作っていったのか、一部システムを抜粋して以下の図に置き換えました。

NP社システム構成図

春田氏:
対外IF(インターフェイス)機能郡に関しては、できるだけサーバーレスにすることで、マイクロサービス化後に落ちづらいような構成にしています。また、できる限りコア機能群・事業システムから独立して稼働できるような形になっています。

NP社システム構成図(対外IF)

春田氏:
事業システムの部分に対しては、マイクロサービスが生成した契約情報の配信を実施。これらを各事業が使う形にして、「マイクロサービスが止まっていると事業システムが動かない」という状態を極力起こさないよう工夫しています。

NP社システム構成図(事業システム)

春田氏:
コア機能群に関しては、イベント駆動でデータフローベースのアーキテクチャにしつつも、一つのデータベースが全体のアーキテクチャの単一障害点にならないように設計しています。

仮にメンテナンス時にデータベースを停止し、上で稼働しているECSのコンシューマーを閉じたとしても、対外的に公開している機能は稼働し続けられるような形にしています。

NP社システム構成図(コア機能群)

選択したアーキテクチャパターン

春田氏:
アーキテクチャパターンは認知負荷の大きさを考えて、マイクロサービスではなくモジュラモノリスに落ち着きました。

NP社選択したアーキテクチャパターン

春田氏:
目指した基本思想は、以下のような状態です。

NP社選択したアーキテクチャパターン②

春田氏:
データフローを取り扱うミドルレイヤーでApache Kafkaを構成しており、申請・審査・契約サービスとそれらのサブドメインのサービスの中に、いろいろなモジュールを積み重ねて作れるようにしてあります。

RDBMSの中にサービスごとのスキーマを区切り、各サービスがRDBMSのスキームを参照するような形にもしています。

採用した設計パターン1:Sagaパターン

春田氏:
設計パターンはイベント駆動で整理しようとSagaパターンを採用しました。結果整合性を担保するために、さまざまなランタイムの上でトランザクションをかけていくことになります。

sagaパターン

春田氏:
ちなみに、Sagaパターンは2種類あります。

sagaパターンの種類①

春田氏:
今回我々が採用したのはオーケストレーション型です。技術的な部分に向き合った上で、システム全体をシンプルにできそうだったからなのと、処理の実行タイムラインに統制をかけたかったからです。

選択したsagaパターン

採用した設計パターン2:イベントソーシング/CQRS

春田氏:
もう1つ気を付けなければならなかったポイントが、イベントソーシングとCQRSのパターンです。

ドメインイベントが唯一信頼できるデータである、という考え方で業務データを設計し、イベントストアにドメインイベントをログデータとして蓄積。更新プロセス側で受け取り、非同期的に反映させていく形で証跡ログを残しています。

イベントソーシング/CQRS

春田氏:
CQRSは、参照するデータを業務データベースに問い合わせ、計算処理した結果をイベントストアに切り出して保存。それを非同期で業務データベースに取り込みます。RDBMSを使っていたとしてもリードレプリカを増殖させて、非同期対応に臨めるような形になっています。

イベントソーシング/CQRS②

採用した設計パターン3:Transactional Outbox

春田氏:
Transactional Outboxも導入しています。業務テーブルとOutboxテーブルを同じRDBMS側に用意し、これらを単一コミットで保存することによって、一部処理に失敗しても全体の処理を巻き戻して不整合が起きないようにする構成です。

Transactional Outbox

春田氏:
これらを実現する上では、Debeziumも採用しました。RDBMSに書き込まれたデータがWALファイルで書き出されるので、Kafka Connectと呼ばれるDebeziumで吸い出し、Kafkaにつなげます。RDBMSに書き込んだものがKafkaのメッセージブローカーに連携されて、イベント駆動で処理を走らせることが可能になっています。

Transactional Outbox②

まとめ:設計パターン

春田氏:
以下が、導入した設計パターンのまとめです。対応規模の拡大に備えて、不整合を防ぐマイクロサービスアーキテクチャ設計を心がけました。

設計パターンまとめ

マイクロサービス化による副作用

春田氏:
マイクロサービス化による副作用は、以下の3つです。

マイクロサービスによる副作用

春田氏:
マイクロサービスを作る時期だと綺麗に体制を組んで進めることは可能なのですが、リリースした後に同様の体制を組めるのかはプロダクト開発戦略次第になります。
戦略によっては、リリース後は保守体制に入り一定の体制縮小も入ることになるので、人を削減し結果的に1人の人が複数のサブドメインのプロダクトを保守する体制になることも往々にしてあります。

ドメイン内のシステムにおいては一定の技術スタックで揃えたりモノリポジトリで認知負荷をできる限り下げて、1人が見れるシステムの範囲を広げやすいようには工夫を行いました。
アーキテクチャに関しては、一つのチームで複数のプロダクトを取り扱うことになり保守対象が増えるので、結果的に認知負荷の向上につながるケースが多かったです。

システムについては、どうしてもネットワークの不具合と戦うことになります。障害面積はモノリスな構成と比べると確実に増え、サービス間の通信障害が起きることを想定した作り込みも必要となるため設計難易度も当然上がります。
またSagaをベースにした際にトランザクションを最小単位で区切っていくことになるので、1オブジェクトの処理のライフサイクルは長くなり完了までの処理時間も延びることになります。
並列実行数を増やしたスケールアウトによるスケーラビリティの恩恵が受けられるトランザクション規模のフェーズに行かないとなかなかパフォーマンス観点の恩恵も感じにくいと思います。

食べログにおけるマイクロサービス化の功罪

食べログのシステム構成図(Webアプリ部分)

栗山氏:
食べログについても発表します。以下は、食べログのシステム構成図のWebアプリ部分の概要です。

食べログシステム構成図

栗山氏:
現在の食べログは巨大なモノリスであるtabelog_baseと、tabelog_baseから機能を切り出した分割システム、それに最初からtabelog_baseとは別のリポジトリで開発した独立システムから成り立ちます。部分的にマイクロサービスアーキテクチャのシステムです。

tabelog_base

栗山氏:
分割したシステムは固有のDBをRead/Writeするものと、メインDBをRead/Writeするものが混在しています。

分割システム

独立システム

栗山氏:
食べログのマイクロサービス化については、大きく2つの歴史に分けて考えています。

マイクロサービスの歴史

栗山氏:
その中で食べログがマイクロサービス化によって追求したかったのは、合成可能性とデプロイの独立です。

食べログのマイクロサービスで追求したかったこと

栗山氏:
デプロイの独立は小さめのモチベーションですが、エンジニアの開発体験を改善したいという思いがありました。

前提:tabelog_base内部の構成

栗山氏:
巨大なモノリスになっているtabelog_baseの内部は、複数のRailsアプリとアプリ間で共有されているライブラリで構成されています。

tabelog_base内部構成

成功事例:ユーザ認証システム

栗山氏:
まずは成功事例として、ユーザ認証システムについてご紹介します。図の通り、ほとんどの機能は共有ライブラリに集約されていたのですが、一部機能はサブシステムに漏れている状態でした。

成功事例 before

栗山氏:
そこで目指したのが、以下のような姿です。認証機能を別のシステムとデータベースにして、tabelog_baseから直接認証情報を使わないようにしようと思いました。

成功事例:目指した姿

栗山氏:
これはユーザ認証機能だけのことなので、短期間でシステムを分割し、データベースの移行にも成功しています。

成功事例:移行過程

栗山氏:
成功要因の一つは、ユーザ認証に詳しいエンジニアが分離を担当したことです。
サブシステムの切り替えも、比較的短期で移行が完了。データベースが固有なので、ALTERのシステム間の影響もなかったのが良かったです。

成功事例:After

失敗事例:kibanシステム

栗山氏:
失敗事例もご紹介します。「kiban」は食べログ用語で、レストランや口コミなど、食べログの主要機能を集約することを試みたシステムでした。

失敗事例:Before

栗山氏:
以下のような姿を目指したのですが、なんだか嫌な予感がしますよね。

失敗事例:目指した姿

栗山氏:
レストランだけでも機能が多数あります。なおかつ結合度が高く分割困難な部分が多かったため、まずはレストラン機能Cだけを分割しました。

失敗事例:移行過程

栗山氏:
すると、レストラン機能がtabelog_baseとkibanに分かれた状態に。

失敗事例:After

栗山氏:
結果的に、「分散されたモノリス」という、マイクロサービスによくあるアンチパターンになってしまいました。

分散されたモノリス

栗山氏:
共有ライブラリの機能はデータベースを共有するAPIとして切り出したのですが、サブシステムAをAPIに切り替えることができませんでした。これが分散されたモノリスという状態です。 現状は、以下のようになっています。

失敗事例の現状

まとめ:kibanシステム事例からのインサイト

栗山氏:
kibanシステムの失敗事例から得たインサイトは、以下の通りです。ビジネス案件の成功が至上命題の開発チームにとって、ビジネスインパクトがない改善に主体性を取り組むのはかなり難しいですね。

kibanシステム事例からのインサイト

食べログにおける大規模なレガシーシステムを段階的に改善していく取り組み

栗山氏:
後半は、マイクロサービス化を手段と悟った期についてご説明します。

マイクロサービス化を手段と悟った期

栗山氏:
成し遂げたかったのは、以下のような内容です。現在はモジュラモノリスアーキテクチャをゴールとして、段階的な改善を行っています。

マイクロサービスで実現したいこと

栗山氏:
まずは、3段階のステップでレガシーなシステムを改善していく取り組みをしています。

レガシーシステムの段階的な改善

[Stpep.1]システムの変更容易性と変更安全性を高める

栗山氏:
ステップ1では、システムの変更容易性と変更安全性を高めます。

システム全体をモダンなインフラ基盤に刷新し、アジリティを備えるということですね。よくアジャイル開発と言いますが、システムの基盤がアジャイルな状態でないと、アジャイル開発をしてもシステムに適応させるのが困難です。

ステップ1

栗山氏:
システム基盤の問題解決のために、複数チームのスコープを決めて集中開発する体制にしました。そのために、当時の姿(As Is)と、目指す姿(To Be)、それをどう実現するか(How)、チームの割当を考えています。

システムの変更容易性と安全性を高める

栗山氏:
マイクロサービス化チームとしては、書籍や他社事例、現状の課題の内容から、食べログに必要なシステム基盤をカタログ化しました。

マイクロサービス基盤カタログ

栗山氏:
さらに、小さく検証・運用を始め、上手くいったら導入を拡大するという方針に。以下の図は左側が2021年3月、右側が2022年3月のカタログで、黄色い「運用中」ステータスの部分が増えてきました。

マイクロサービス基盤カタログの効果

マイクロサービス基盤の事例:データ同期基盤のBefore・After

栗山氏:
上手くいったマイクロサービス基盤の事例のビフォー・アフターもご紹介します。以下は業務データを検索エンジンに反映させるための機能に関する概要説明なのですが、これまではレガシーでパフォーマンスが悪いという問題がありました。

マイクロサービス基盤の事例:Before

栗山氏:
「リアルタイムで8時間の更新」という目標を掲げ、春田さんの発表でも登場したDebeziumを使い、パフォーマンスを向上。全件の所要時間の改善率が110倍になりました。

マイクロサービス基盤の事例:After

栗山氏:
3.5時間あれば全データを更新できるので、大胆な仕様変更も楽になりましたね。

まとめ:システムの変更容易性と変更安全性を高める活動を通して

栗山氏:
以下は現時点までの簡単なまとめです。システム基盤の改善から始めると、過渡期にもメリットを得られるのがうれしいですね。

まとめ:システムの変更容易性と安全性を高める活動を通して

[Step.2]モノリスのレポジトリを小さく速く改善する

栗山氏:
システム基盤をモダンにしたので、次はいよいよアプリケーションの改善です。

ステップ2

栗山氏:
改善をするにしても、長年メンテナンスをしているリポジトリには負債が溜まっています。そこでデッドメソッドをできるだけ機械的に検知して削除するシステムを設けました。それが以下のようなものです。

密結合で技術負債が溜まったシステムを分割するにあたり

栗山氏:
こういうメソッドの実行実績を、食べログではBigQueryに投入。ファイル名や期間指定で不要な疑いのあるメソッドが一覧可能になっています。

デッドメソッドやコードを検知して削除する仕組み

栗山氏:
実行していないからといって削除していいわけではありません。必ず調査してから削除する必要があります。

今は調査削除の専任が1名、レビュアーが兼任で数名という体制で、1ヶ月に約300のデッドメソッドを削除しています。

デッドメソッドやコードを検知して削除する仕組みの効果

全体のまとめ:「食べログ」のマイクロサービス化への挑戦を通じて

栗山氏:
全体のまとめです。マイクロサービス化は目的ではなく手段であり、最初に取り組んだように「分けること」を目的にするとろくなことになりません。また、レガシーなシステムは段階的に改善するのがベターです。

まとめ

Q&A

なぜマイクロサービスで認知負荷が大きくなってしまったのか?

Q.マイクロサービスは認知負荷が高いという話があったが、関心事ごとにサービスを分離したほうが認知負荷は少ないように思える。それはモジュラーモノリスにすることによって解決することだったのでしょうか?組織論で、人が変わるときにモノリスシステム全体を知らないと改修できない状態のほうが認知負荷は高いように思えますが、いかがでしょうか?

春田氏:
最初はサブドメインごとにチームを組めましたが、リリース後まで維持するのが難しかったです。ある程度スモールなチームの中で複数のプロダクトを見るフェーズに差し掛かると、認知負荷がどうしても上がってしまいました。

モジュラーモノリスで疎結合を保つための制御はどうしている?

Q.モジュラーモノリスだとマイクロサービスに比べて疎結合性を保つのに制御を入れないと、思わぬ依存が発生しやすくなると感じています。静的解析を行うなどの制御はされていますか?

春田氏:
リポジトリの設計上、それぞれのサービスが別の関心領域のソースコードを参照できないような構成にすることで回避していました。興味関心領域でリポジトリを分けて、相互参照が発生しないような構成ですね。

Kafkaの運用管理はどうしている?

Q.Kafkaは運用管理が難しいと聞いたことがあるのですが、内製で管理されていますか?また、Cloud Pub/SubやSQSなどのクラウドサービスもありますが、選択肢にありましたか?

栗山氏:
SQSや Cloud Pub/Sub を使いたいとも思ったが、Kafkaを運用するならそちらに統合した方がいいという判断でKafkaを使っています。将来的にはAWSのマネージドKafkaを使うなどの選択肢を考えています。

マイクロサービス間の共通概念はどのように実現している?

Q.マイクロサービス間の共通の概念(利用者とか事業所とか)はどのように実現されていますか?共有DBとかでしょうか?システムが分かれるとユニーク性を担保するのは仕組みやルールが必要な気がしています。疎結合にしたいけどできないデータもありますよね?データ同期基盤がそれを実現しているのでしょうか?

栗山氏:
食べログの認証基盤ではAPIを用いて、2つのシステム間で同期しています。事業所のような概念を利用しているシステムはまだマイクロサービス化していないので、共通のDBをモジュラーモノリスの複数システムで参照している状態です。

ドメイン境界の定義のための取り組みは?

Q.マイクロサービスでもモジュラーモノリスでも、ドメイン境界の定義が大切だと思いますが、各社境界定義において取り組んでいることはありますでしょうか?

春田氏:
境界定義については、ビジネス部門と対話しています。一つのサブドメインとして切り出したほうが、自律的な改善を見込めるところを見つける動きをした感じですね。

栗山氏:
食べログはエンジニアが多くそれぞれ課題も異なるので、データモデリングからのアプローチやドメイン駆動設計などで取り組んでいて、統一はしてない状態です。

モジュールごとに使用言語は変えている?

Q.モジュールごとに使用言語など変えていますでしょうか?分散システムを導入する際、技術的チャレンジを狙いにするケースも伺っておりまして……。

春田氏:
使用言語は変えていません。認知負荷をできるかぎり下げたかったですしね。

栗山氏:
同じです。Rubyエンジニアが多かったため、そこからほかの言語にシフトしたいエンジニアは少なかったです。書籍や事例でも、技術スタックはある程度統一すべきという話が多いです。

マイクロサービスを作る上で教育や研修は実施している?

Q.マイクロサービスを作る上で、教育や研修をしたりするのでしょうか?モノリスで生きていたエンジニアにいきなりやってもらうのはハードルが高そうで、工夫されていることはありますか?

春田氏:
今回お話しした設計パターンなどを教育コンテンツとして内部資料にまとめています。まずはドメイン知識を得て、実際にシステムで動かすとどうなるのかをできるかぎり研修プランに組むようにしています。

栗山氏:
今はマイクロサービス化を推進していないのでマイクロサービスのオンボーディングはしていませんが、システム基盤についてはカタログを用意して説明しやすい状態にし、どういう理想的なアーキテクチャにしたらいいのか、関わったチームに啓発していますね。

マイクロサービス関連記事のご紹介

ここからはマイクロサービス関連の記事をご紹介します。

マイクロサービスアーキテクチャの特徴

こちらの記事ではマイクロサービスアーキテクチャとは?という基礎的な部分から、メリットやデメリットなどの解説までしています。

Kubernetesを用いてマイクロサービスアーキテクチャへと刷新

こちらの記事ではプロ人材活用事例としてブルーテック株式会社様を取材。主要プロダクト「Knowledge Suite(ナレッジスイート)」におけるKubernetesを用いたマイクロサービスアーキテクチャへの刷新プロジェクトについて取締役雄川様にお話を伺っています。

マイクロサービスの概念をフロントエンドに適用

こちらの記事ではマイクロフロントエンドについて解説。日本国内でもまだ活用事例が少ないなか、3社のマイクロフロントエンド活用事例を一挙に取り上げています。

まとめ

今回は「マイクロサービス」について、ネットプロテクションズ社・カカクコム社それぞれドメインの異なるサービスにおける適用事例を伺いましたがいかがでしたか?
技術的チャレンジによってチームに知見が溜まるなどプラスの側面もありながら、一方で技術・組織の両面で困難も伴う、一層慎重な判断が求められる技術なのだと改めて感じました。
分割も1つの選択肢として持ちながら、自社にとってどのようなアーキテクチャが最適なのか考え続けていきましょう。

FLEXYとはABOUT FLEXY

『FLEXY』はエンジニア・デザイナー・CTO・技術顧問を中心に
週1~5日のさまざまな案件を紹介するサービスです