マイクロサービスの分割境界線

これ何

マイクロサービスの分割点の通説をまとめてみようと思う。

通例

How to Partition Your Data Between Microservices

2つの競合するルールが存在する

  1. データの所有権
    • データの更新、保持に責任を持つこと
  2. ローカリティ
    • マイクロサービスが必要とするデータは多くのサービスの近くにあるべき。可能ならサービス自体に含まれていること

※この2つは対立する場合があり、両方を満たすにはデータを複数の場所に保存しなれけばならなくなる。それはOKだが、重要なのはそれら複数のストレージの内、1つのストレージだけが権威あるソースとして全体が成り立っていることだ。

データの所有権

マイクロサービスの責務を決める第一の要因はサービスが持つビジネス能力(Business Capabilities)となるべき。ビジネス能力に属するものはすべてマイクロサービスに実装されるべき(ここにはデータの保存も含まれる)。特定のデータをどのマイクロサービスが担当しているかを決めるには、どのビジネスプロセスがそのデータを最新の状態に保つのかを把握することが必要になる。

ローカリティ

ローカリティは各データの所有権の次に重要。

サービスが自分のDBに問い合わせのと別のサービスに問い合わせるのでは、速度と信頼性において大きな違いがある(自分のDBに問い合わせる方が速度・信頼性共に高くなる)。マイクロサービス間では各サービスが保持しているデータを参照する必要が出てくるが、1つのサービスがダウンするとそれに伴って別のサービスがダウンしたり、速度低下が起こる等の問題が起こる。この結合状態を緩めるには受け取り側はデータをキャッシュすること、データの所有者はキャッシュヘッダなどを使いデータのライフサイクルを管理すること(キャッシュ扱うのは受け取り側なので、結局受け取り側の責務な気もするが)。

また別の方法としてデータのミラーを持っておくことも考えられる。他のサービスが所有しているデータを参照するためにそのサービスへのクエリ(API call etc)ではなく、そのサービスが所有しているデータを読み取り専用として自分のDBに保持し、他サービスへのクエリを自分のDBへのクエリに置き換えることだ。この場合、データを所有しているサービスから取得したデータをコピーとして格納し、必要に応じ権威データを元に更新することが求められる。書き込み時の複雑性が増すが、読み取り時の複雑性は下がる。このような構成はイベントモデルに基づいていることが多い。

martinfowler.comのMicroservices

マイクロサービスアーキテクチャを9個の特性に分解したドキュメント。その中から分割点に関わる部分だけ抜粋する

Organized around Business Capabilities

テクノロジーに焦点を当てサービスを分割すると単純な変更でも時間を必要とすることになってしまう。マイクロサービスの分割アプローチはビジネス能力(Business Capabilities)を中心に組織化されていく。

Decentralized Data Management

データ管理の分散化を行うとUserモデルがサービスAとBで違う呼ばれ方をしたり、表示される属性が異なったりすることが起こる。この問題への有用な考え方としてDDDのバウンデッドコンテキストがある。DDDでは、複雑なドメインを複数のバウンデッドコンテキストに分割し、それらの間の関係をマッピングします。このプロセスはモノリシック・アーキテクチャとマイクロサービス・アーキテクチャの両方に有効ですが、サービスとコンテキストの境界には自然な相関関係があり、それが明確化を助け、ビジネス能力(Business Capabilities)のセクションで説明するように、分離を強化します。

ドメイン分析を使用したマイクロサービスのモデル化

Microservices should be designed around business capabilities, not horizontal layers such as data access or messaging.(マイクロサービスは、データ アクセスやメッセージングなどの水平レイヤーではなく、ビジネス機能に基づいて設計する必要があります)

マイクロサービスには疎結合と機能の高い凝集度が必要。個々のサービスの境界定義がうまくできないと、サービス間の非表示の依存関係、密結合、不完全なデザインのインターフェイスなどの好ましくない特徴を持った設計になる可能性がある。

他のサービスを同時に更新せずにサービスを変更できる場合、マイクロサービス同士はゆるやかに結び付いています。

ここまでをまとめる

Business capabilitiesに沿ってサービスを分割し、チームを配置することが取るべきアプローチとして紹介されている。

Business capabilitiesをどう定義するか

マーティンファウラーの記事でも記述があったが、マイクロソフトからもDDDを使ってバウンデッドコンテキストを作成するのがオススメされていた。この記事では、例に挙げられたサービスをDDDを使ってどのように分割し認識するか、までがチュートリアルぽくまとめられていたので、これを見ると良さそう。

その他参考資料