マイクロサービスのデータに関する考慮事項
この記事では、マイクロサービス アーキテクチャでデータを管理するための考慮事項について説明します。 すべてのマイクロサービスが独自のデータを管理するため、データの整合性とデータの整合性は重要な課題です。
マイクロサービスの基本原則は、各サービスが独自のデータを管理することです。 2 つのサービスでデータ ストアを共有しないでください。 代わりに、各サービスは、他のサービスが直接アクセスできない独自のプライベート データ ストアを担当します。
この規則の理由は、サービス間の意図しない結合を回避するためです。これは、サービスが同じ基になるデータ スキーマを共有している場合に発生する可能性があります。 データ スキーマに変更がある場合は、そのデータベースに依存するすべてのサービスで変更を調整する必要があります。 各サービスのデータ ストアを分離することで、変更の範囲を制限し、真に独立したデプロイの機敏性を維持できます。 もう 1 つの理由は、各マイクロサービスに独自のデータ モデル、クエリ、または読み取り/書き込みパターンがある可能性があるということです。 共有データ ストアを使用すると、各チームが特定のサービスのデータ ストレージを最適化する機能が制限されます。
このアプローチは、1 つのアプリケーション内で複数のデータ ストレージ テクノロジを使用することで、自然に ポリグロットの永続化 につながります。 1 つのサービスでは、ドキュメント データベースの読み取り時スキーマ機能が必要になる場合があります。 もう 1 つは、RDBMS によって提供される参照整合性が必要な場合があります。 各チームは、サービスに最適な選択を自由に行うことができます。
注
サービスが同じ物理データベース サーバーを共有しても問題ありません。 この問題は、サービスが同じスキーマを共有している場合、または同じデータベース テーブルのセットに対する読み取りと書き込みを行う場合に発生します。
課題
データの管理に対するこの分散アプローチには、いくつかの課題が生じます。 まず、データ ストア全体に冗長性があり、同じ項目のデータが複数の場所に表示される場合があります。 たとえば、データはトランザクションの一部として格納され、分析、レポート、アーカイブのために他の場所に格納される場合があります。 データが重複またはパーティション分割されると、データの整合性と整合性の問題が発生する可能性があります。 データ リレーションシップが複数のサービスにまたがる場合、従来のデータ管理手法を使用してリレーションシップを適用することはできません。
従来のデータ モデリングでは、"1 つの場所に 1 つのファクト" というルールが使用されます。すべてのエンティティは、スキーマに 1 回だけ表示されます。 他のエンティティは、そのエンティティへの参照を保持している可能性がありますが、重複することはできません。 従来のアプローチの明らかな利点は、更新が 1 か所で行われ、データの整合性に関する問題を回避できることです。 マイクロサービス アーキテクチャでは、更新プログラムがサービス間でどのように伝達されるか、およびデータが厳密な整合性なしで複数の場所に表示される場合に最終的な整合性を管理する方法を検討する必要があります。
データを管理する方法
どの場合も正しいアプローチは 1 つではありませんが、マイクロサービス アーキテクチャでデータを管理するための一般的なガイドラインを次に示します。
コンポーネントごとに必要な整合性レベルを定義し、可能な場合は最終的な整合性を優先します。 強力な整合性または ACID トランザクションが必要なシステム内の場所と、最終的な整合性が許容される場所を理解します。 詳細なコンポーネント ガイダンスについては、「 戦術的 DDD を使用してマイクロサービスを設計する 」を参照してください。
強力な一貫性の保証が必要な場合、1 つのサービスが特定のエンティティの信頼できるソースを表し、API を介して公開される可能性があります。 他のサービスは、データの独自のコピーまたはデータのサブセットを保持する場合があり、最終的にはマスター データと一致しますが、信頼できるソースとは見なされません。 たとえば、顧客注文サービスとレコメンデーション サービスを備えた e コマース システムを想像します。 レコメンデーション サービスは注文サービスからのイベントをリッスンする可能性がありますが、顧客が払い戻しを要求した場合、完全なトランザクション履歴を含むのは、推奨サービスではなく注文サービスです。
トランザクションの場合は、 Scheduler Agent Supervisor や 補正トランザクション などのパターンを使用して、複数のサービス間でデータの一貫性を維持します。 複数のサービス間で部分的な障害が発生しないように、複数のサービスにまたがる作業単位の状態をキャプチャする追加のデータを格納する必要がある場合があります。 たとえば、マルチステップ トランザクションの進行中は、永続的なキューに作業項目を保持します。
サービスに必要なデータのみを格納します。 サービスには、ドメイン エンティティに関する情報のサブセットのみが必要な場合があります。 たとえば、出荷有界コンテキストでは、特定の配送に関連付けられている顧客を把握する必要があります。 ただし、顧客の請求先住所は必要ありません。これはアカウントの境界付きコンテキストによって管理されます。 ここでは、ドメインについて慎重に検討し、DDD アプローチを使用すると役立ちます。
サービスが一貫性があり、疎結合されているかどうかを検討します。 2 つのサービスが相互に情報を交換し続け、その結果、API が頻繁に発生する場合は、2 つのサービスをマージするか、機能をリファクタリングすることで、サービスの境界を再描画することが必要になる場合があります。
イベント ドリブン アーキテクチャ スタイルを使用します。 このアーキテクチャ スタイルでは、パブリック モデルまたはエンティティが変更されたときに、サービスによってイベントが発行されます。 関心のあるサービスは、これらのイベントをサブスクライブできます。 たとえば、別のサービスでイベントを使用して、クエリに適したデータの具体化されたビューを構築できます。
イベントを所有するサービスでは、パブリッシャーとサブスクライバー間の緊密な結合を回避するために、イベントのシリアル化と逆シリアル化を自動化するために使用できるスキーマを発行する必要があります。 JSON スキーマ、または Microsoft Bond、Protobuf、Avro などのフレームワークを検討してください。
大規模なイベントはシステムのボトルネックになる可能性があるため、集計またはバッチ処理を使用して総負荷を減らすことを検討してください。
例: ドローン配送アプリケーションのデータ ストアの選択
このシリーズの前の記事では、実行中の例としてドローン配送サービスについて説明します。 シナリオと対応する参照実装の詳細 については、こちらをご覧ください。 この例は、航空機および航空宇宙産業に最適です。
要約すると、このアプリケーションでは、ドローンによる配送をスケジュールするための複数のマイクロサービスを定義します。 ユーザーが新しい配信をスケジュールすると、クライアント要求には、配送に関する情報 (集荷場所や降車場所など)、およびパッケージに関する情報 (サイズや重量など) が含まれます。 この情報により、作業単位が定義されます。
さまざまなバックエンド サービスでは、要求内の情報のさまざまな部分が考慮され、読み取りと書き込みのプロファイルも異なります。
配信サービス
配信サービスには、現在スケジュールされている、または進行中のすべての配信に関する情報が格納されます。 ドローンからのイベントをリッスンし、進行中の配送の状態を追跡します。 また、配信状態が更新されたドメイン イベントも送信されます。
ユーザーがパッケージを待っている間、配信の状態を頻繁に確認することが期待されます。 そのため、配信サービスには、長期的なストレージよりもスループット (読み取りと書き込み) を重視するデータ ストアが必要です。 また、配信サービスは複雑なクエリや分析を実行せず、特定の配信の最新の状態をフェッチするだけです。 配信サービス チームは、読み取り/書き込みパフォーマンスが高いため、Azure Cache for Redis を選択しました。 Redis に格納されている情報の有効期間は比較的短くなります。 配信が完了すると、配信履歴サービスが記録のシステムになります。
配信履歴サービス
配信履歴サービスは、配信サービスからの配信状態イベントをリッスンします。 このデータは、長期的なストレージに格納されます。 この履歴データには、データ ストレージ要件が異なる 2 つの異なるユース ケースがあります。
最初のシナリオは、ビジネスを最適化したり、サービスの品質を向上させたりするために、データ分析のためにデータを集計することです。 配信履歴サービスでは、データの実際の分析は実行されません。 インジェストとストレージのみを担当します。 このシナリオでは、さまざまなデータ ソースに対応するためのスキーマオンリード アプローチを使用して、大量のデータセットに対するデータ分析用にストレージを最適化する必要があります。 Azure Data Lake Store は、このシナリオに適しています。 Data Lake Store は、Hadoop 分散ファイル システム (HDFS) と互換性のある Apache Hadoop ファイル システムであり、データ分析シナリオのパフォーマンスに合わせて調整されています。
もう 1 つのシナリオでは、配信が完了した後にユーザーが配信の履歴を検索できるようにします。 このシナリオでは、Azure Data Lake は最適化されていません。 最適なパフォーマンスを得るための Microsoft では、日付でパーティション分割されたフォルダー内の Data Lake に時系列データを格納することをお勧めします。 (パフォーマンスについては、 Azure Data Lake Store のチューニングに関するページを参照してください)。 ただし、その構造は、ID で個々のレコードを検索する場合には最適ではありません。 タイムスタンプもわかっている場合を除き、ID による検索ではコレクション全体をスキャンする必要があります。 そのため、配信履歴サービスでは、履歴データのサブセットも Azure Cosmos DB に格納され、すばやく検索できます。 レコードは、Azure Cosmos DB に無期限に残る必要はありません。 古い配送は、たとえば 1 か月後にアーカイブできます。 これは、時々バッチ 処理を実行することで行うことができます。 古いデータをアーカイブすると、Data Lake からの履歴レポートでデータを使用できる状態を維持しながら、Cosmos DB のコストを削減できます。
パッケージ サービス
Package サービスには、すべてのパッケージに関する情報が格納されます。 パッケージのストレージ要件は次のとおりです。
- 長期ストレージ。
- 大量のパッケージを処理でき、高い書き込みスループットが必要です。
- パッケージ ID による単純なクエリをサポートします。 参照整合性の複雑な結合や要件はありません。
パッケージ データはリレーショナルではないため、ドキュメント指向データベースが適切であり、Azure Cosmos DB ではシャード 化されたコレクションを使用して高スループットを実現できます。 パッケージ サービスで作業するチームは MEAN スタック (MongoDB、Express.js、AngularJS、Node.js) に精通しているため、Azure Cosmos DB 用 の MongoDB API を 選択します。 これにより、MongoDB での既存のエクスペリエンスを活用しながら、マネージド Azure サービスである Azure Cosmos DB の利点を得られます。
次のステップ
マイクロサービス アーキテクチャの一般的な課題を軽減するのに役立つ設計パターンについて説明します。
マイクロサービス の設計パターンの
関連リソース
- ドメイン分析を使用してマイクロサービス をモデル化する
- マイクロサービス アーキテクチャ を設計する
- マイクロサービス 用の API を設計する
- マイクロサービス アーキテクチャの設計