マイクロサービス化による未来は本当にネガティブだけなのか? [FLEXY meetup イベントレポート]
2023年7月26日に開催されたFLEXY meetupのテーマは「マイクロサービス」です。
システム分割によるメリットを得ようと、機能やサービス単位のマイクロサービス化に挑戦した数多くの企業事例をこれまで耳にしました。
一方取り組んだ結果、難易度の高さから多くの功罪が発生しているのも事実です。
「マイクロサービスの実践がもたらす結果は本当に負の側面だけなのか?」
今回はマイクロサービスのメリット・デメリットをフラットに語るべくカカクコム社の栗山さん、ネットプロテクションズ社の春田さんをお招きし、実際に直面した課題や現在試みているシステム戦略などについて広く伺いました。
目次
登壇者
春田 岬さん|株式会社ネットプロテクションズ ソリューションアーキテクトグループ兼BtoBディベロップメントグループ 統括責任者 @harumisa31
後払い決済の会社でフリーダムに活動するソリューションアーキテクト。
AWS移行や、IaCの導入、アーキテクチャ刷新、マルチアカウント化、マイクロサービス構築と色んなことをやっています。
栗山 友樹さん|株式会社カカクコム 食べログシステム本部 技術部 マイクロサービス化チームリーダー @weakboson
食とSNSが好きで、両方一緒に開発できる食べログにジョインした食い倒れITデベロッパ。
口コミ投稿フロントエンドから、レストラン検索バックエンド、インフラのIaC化まであちこちなんでも担当した後2019年から現チームでマイクロサービス化を進めている。
NP掛け払いにおけるマイクロサービス化実例
解決したい領域・マイクロサービス化した理由
春田氏:
当社がマイクロサービス化に挑戦した理由は3つあります。
- 特定の決済プロダクトに依存しない横断的な取引先情報の管理を行いたい
- 包括加盟など複雑な契約形態が出てきた場合に備えて横断的に利用し契約情報を管理できる状態を作りたい
- 加盟審査の業務プロセスを一本化し機能を一本化させることで業務を効率化したい
春田氏:
また、マイクロサービスのメリットとして追求したかったのは、合成可能性と組織の自律性の2点です。
システム構成図
春田氏:
当社がドメインをどう作っていったのか、一部システムを抜粋して以下の図に置き換えました。
春田氏:
対外IF(インターフェイス)機能郡に関しては、できるだけサーバーレスにすることで、マイクロサービス化後に落ちづらいような構成にしています。また、できる限りコア機能群・事業システムから独立して稼働できるような形になっています。
春田氏:
事業システムの部分に対しては、マイクロサービスが生成した契約情報の配信を実施。これらを各事業が使う形にして、「マイクロサービスが止まっていると事業システムが動かない」という状態を極力起こさないよう工夫しています。
春田氏:
コア機能群に関しては、イベント駆動でデータフローベースのアーキテクチャにしつつも、一つのデータベースが全体のアーキテクチャの単一障害点にならないように設計しています。
仮にメンテナンス時にデータベースを停止し、上で稼働しているECSのコンシューマーを閉じたとしても、対外的に公開している機能は稼働し続けられるような形にしています。
選択したアーキテクチャパターン
春田氏:
アーキテクチャパターンは認知負荷の大きさを考えて、マイクロサービスではなくモジュラモノリスに落ち着きました。
春田氏:
目指した基本思想は、以下のような状態です。
春田氏:
データフローを取り扱うミドルレイヤーでApache Kafkaを構成しており、申請・審査・契約サービスとそれらのサブドメインのサービスの中に、いろいろなモジュールを積み重ねて作れるようにしてあります。
RDBMSの中にサービスごとのスキーマを区切り、各サービスがRDBMSのスキームを参照するような形にもしています。
採用した設計パターン1:Sagaパターン
春田氏:
設計パターンはイベント駆動で整理しようとSagaパターンを採用しました。結果整合性を担保するために、さまざまなランタイムの上でトランザクションをかけていくことになります。
春田氏:
ちなみに、Sagaパターンは2種類あります。
春田氏:
今回我々が採用したのはオーケストレーション型です。技術的な部分に向き合った上で、システム全体をシンプルにできそうだったからなのと、処理の実行タイムラインに統制をかけたかったからです。
採用した設計パターン2:イベントソーシング/CQRS
春田氏:
もう1つ気を付けなければならなかったポイントが、イベントソーシングとCQRSのパターンです。
ドメインイベントが唯一信頼できるデータである、という考え方で業務データを設計し、イベントストアにドメインイベントをログデータとして蓄積。更新プロセス側で受け取り、非同期的に反映させていく形で証跡ログを残しています。
春田氏:
CQRSは、参照するデータを業務データベースに問い合わせ、計算処理した結果をイベントストアに切り出して保存。それを非同期で業務データベースに取り込みます。RDBMSを使っていたとしてもリードレプリカを増殖させて、非同期対応に臨めるような形になっています。
採用した設計パターン3:Transactional Outbox
春田氏:
Transactional Outboxも導入しています。業務テーブルとOutboxテーブルを同じRDBMS側に用意し、これらを単一コミットで保存することによって、一部処理に失敗しても全体の処理を巻き戻して不整合が起きないようにする構成です。
春田氏:
これらを実現する上では、Debeziumも採用しました。RDBMSに書き込まれたデータがWALファイルで書き出されるので、Kafka Connectと呼ばれるDebeziumで吸い出し、Kafkaにつなげます。RDBMSに書き込んだものがKafkaのメッセージブローカーに連携されて、イベント駆動で処理を走らせることが可能になっています。
まとめ:設計パターン
春田氏:
以下が、導入した設計パターンのまとめです。対応規模の拡大に備えて、不整合を防ぐマイクロサービスアーキテクチャ設計を心がけました。
マイクロサービス化による副作用
春田氏:
マイクロサービス化による副作用は、以下の3つです。
春田氏:
マイクロサービスを作る時期だと綺麗に体制を組んで進めることは可能なのですが、リリースした後に同様の体制を組めるのかはプロダクト開発戦略次第になります。
戦略によっては、リリース後は保守体制に入り一定の体制縮小も入ることになるので、人を削減し結果的に1人の人が複数のサブドメインのプロダクトを保守する体制になることも往々にしてあります。
ドメイン内のシステムにおいては一定の技術スタックで揃えたりモノリポジトリで認知負荷をできる限り下げて、1人が見れるシステムの範囲を広げやすいようには工夫を行いました。
アーキテクチャに関しては、一つのチームで複数のプロダクトを取り扱うことになり保守対象が増えるので、結果的に認知負荷の向上につながるケースが多かったです。
システムについては、どうしてもネットワークの不具合と戦うことになります。障害面積はモノリスな構成と比べると確実に増え、サービス間の通信障害が起きることを想定した作り込みも必要となるため設計難易度も当然上がります。
またSagaをベースにした際にトランザクションを最小単位で区切っていくことになるので、1オブジェクトの処理のライフサイクルは長くなり完了までの処理時間も延びることになります。
並列実行数を増やしたスケールアウトによるスケーラビリティの恩恵が受けられるトランザクション規模のフェーズに行かないとなかなかパフォーマンス観点の恩恵も感じにくいと思います。
食べログにおけるマイクロサービス化の功罪
食べログのシステム構成図(Webアプリ部分)
栗山氏:
食べログについても発表します。以下は、食べログのシステム構成図のWebアプリ部分の概要です。
栗山氏:
現在の食べログは巨大なモノリスであるtabelog_baseと、tabelog_baseから機能を切り出した分割システム、それに最初からtabelog_baseとは別のリポジトリで開発した独立システムから成り立ちます。部分的にマイクロサービスアーキテクチャのシステムです。
栗山氏:
分割したシステムは固有のDBをRead/Writeするものと、メインDBをRead/Writeするものが混在しています。
栗山氏:
食べログのマイクロサービス化については、大きく2つの歴史に分けて考えています。
栗山氏:
その中で食べログがマイクロサービス化によって追求したかったのは、合成可能性とデプロイの独立です。
栗山氏:
デプロイの独立は小さめのモチベーションですが、エンジニアの開発体験を改善したいという思いがありました。
前提:tabelog_base内部の構成
栗山氏:
巨大なモノリスになっているtabelog_baseの内部は、複数のRailsアプリとアプリ間で共有されているライブラリで構成されています。
成功事例:ユーザ認証システム
栗山氏:
まずは成功事例として、ユーザ認証システムについてご紹介します。図の通り、ほとんどの機能は共有ライブラリに集約されていたのですが、一部機能はサブシステムに漏れている状態でした。
栗山氏:
そこで目指したのが、以下のような姿です。認証機能を別のシステムとデータベースにして、tabelog_baseから直接認証情報を使わないようにしようと思いました。
栗山氏:
これはユーザ認証機能だけのことなので、短期間でシステムを分割し、データベースの移行にも成功しています。
栗山氏:
成功要因の一つは、ユーザ認証に詳しいエンジニアが分離を担当したことです。
サブシステムの切り替えも、比較的短期で移行が完了。データベースが固有なので、ALTERのシステム間の影響もなかったのが良かったです。
失敗事例:kibanシステム
栗山氏:
失敗事例もご紹介します。「kiban」は食べログ用語で、レストランや口コミなど、食べログの主要機能を集約することを試みたシステムでした。
栗山氏:
以下のような姿を目指したのですが、なんだか嫌な予感がしますよね。
栗山氏:
レストランだけでも機能が多数あります。なおかつ結合度が高く分割困難な部分が多かったため、まずはレストラン機能Cだけを分割しました。
栗山氏:
すると、レストラン機能がtabelog_baseとkibanに分かれた状態に。
栗山氏:
結果的に、「分散されたモノリス」という、マイクロサービスによくあるアンチパターンになってしまいました。
栗山氏:
共有ライブラリの機能はデータベースを共有するAPIとして切り出したのですが、サブシステムAをAPIに切り替えることができませんでした。これが分散されたモノリスという状態です。
現状は、以下のようになっています。
まとめ:kibanシステム事例からのインサイト
栗山氏:
kibanシステムの失敗事例から得たインサイトは、以下の通りです。ビジネス案件の成功が至上命題の開発チームにとって、ビジネスインパクトがない改善に主体性を取り組むのはかなり難しいですね。
食べログにおける大規模なレガシーシステムを段階的に改善していく取り組み
栗山氏:
後半は、マイクロサービス化を手段と悟った期についてご説明します。
栗山氏:
成し遂げたかったのは、以下のような内容です。現在はモジュラモノリスアーキテクチャをゴールとして、段階的な改善を行っています。
栗山氏:
まずは、3段階のステップでレガシーなシステムを改善していく取り組みをしています。
[Stpep.1]システムの変更容易性と変更安全性を高める
栗山氏:
ステップ1では、システムの変更容易性と変更安全性を高めます。
システム全体をモダンなインフラ基盤に刷新し、アジリティを備えるということですね。よくアジャイル開発と言いますが、システムの基盤がアジャイルな状態でないと、アジャイル開発をしてもシステムに適応させるのが困難です。
栗山氏:
システム基盤の問題解決のために、複数チームのスコープを決めて集中開発する体制にしました。そのために、当時の姿(As Is)と、目指す姿(To Be)、それをどう実現するか(How)、チームの割当を考えています。
栗山氏:
マイクロサービス化チームとしては、書籍や他社事例、現状の課題の内容から、食べログに必要なシステム基盤をカタログ化しました。
栗山氏:
さらに、小さく検証・運用を始め、上手くいったら導入を拡大するという方針に。以下の図は左側が2021年3月、右側が2022年3月のカタログで、黄色い「運用中」ステータスの部分が増えてきました。
マイクロサービス基盤の事例:データ同期基盤のBefore・After
栗山氏:
上手くいったマイクロサービス基盤の事例のビフォー・アフターもご紹介します。以下は業務データを検索エンジンに反映させるための機能に関する概要説明なのですが、これまではレガシーでパフォーマンスが悪いという問題がありました。
栗山氏:
「リアルタイムで8時間の更新」という目標を掲げ、春田さんの発表でも登場したDebeziumを使い、パフォーマンスを向上。全件の所要時間の改善率が110倍になりました。
栗山氏:
3.5時間あれば全データを更新できるので、大胆な仕様変更も楽になりましたね。
まとめ:システムの変更容易性と変更安全性を高める活動を通して
栗山氏:
以下は現時点までの簡単なまとめです。システム基盤の改善から始めると、過渡期にもメリットを得られるのがうれしいですね。
[Step.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つの選択肢として持ちながら、自社にとってどのようなアーキテクチャが最適なのか考え続けていきましょう。