web-dev-qa-db-ja.com

マイクロサービス全体のデータの一貫性

通常、各マイクロサービスには独自のデータがありますが、特定のエンティティは複数のサービスで一貫している必要があります。

マイクロサービスアーキテクチャなどの高度に分散されたランドスケープでのこのようなデータ一貫性要件の場合、設計の選択肢は何ですか?もちろん、単一のDBがすべてのサービスの状態を管理する共有データベースアーキテクチャは望ましくありません。これは、分離とシェアードナッシングの原則に違反します。

マイクロサービスは、エンティティが作成、更新、または削除されたときにイベントを公開できることを理解しています。このイベントに関心のある他のすべてのマイクロサービスは、それぞれのデータベース内のリンクされたエンティティを適宜更新できます。

これは実行可能ですが、サービス全体で多くの注意深い調整されたプログラミング作業につながります。

Akkaまたは他のフレームワークでこのユースケースを解決できますか?どうやって?

EDIT1:
明確にするために以下の図を追加します。
基本的に、このデータ一貫性の問題を解決できるフレームワークが現在利用できるかどうかを理解しようとしています。

キューには、RabbitMQやQpidなどのAMQPソフトウェアを使用できます。データ整合性フレームワークの場合、現在Akkaや他のソフトウェアが役立つかどうかはわかりません。それとも、このシナリオはあまり一般的ではなく、フレームワークを必要としないようなアンチパターンですか?
enter image description here

23
Santanu Dey

Microservicesアーキテクチャスタイルは、組織が開発時および実行時に独立したサービスを所有する小さなチームを持つことを可能にします。これを参照してください read 。そして最も難しいのは、便利な方法でサービスの境界を定義することです。アプリケーションを分割する方法により、要件が複数のサービスに頻繁に影響することに気付いた場合、サービスの境界を再考する必要があります。サービス間でエンティティを共有する必要性が強いと感じた場合も同様です。

したがって、一般的なアドバイスは、そのようなシナリオを避けるために非常に一生懸命努力することです。ただし、これを回避できない場合があります。多くの場合、優れたアーキテクチャは適切なトレードオフを行うことに関するものなので、ここでいくつかのアイデアを示します。

  1. 直接のDB依存関係ではなく、サービスインターフェイス(API)を使用して依存関係を表現することを検討してください。これにより、各サービスチームは必要に応じて内部データスキーマを変更でき、依存関係に関してはインターフェイスの設計のみを考慮することができます。これは、依存するすべてのマイクロサービスと一緒にDB設計を変更する(おそらく同時に)のではなく、追加のAPIを追加し、古いAPIを徐々に廃止する方が簡単なため便利です。つまり、古いAPIが引き続きサポートされている限り、新しいMicroserviceバージョンを個別に展開できます。これは、多くのマイクロサービスアプローチの先駆者であったAmazon CTOが推奨するアプローチです。ここに彼との 2006年のインタビュー の推奨される読み物があります。

  2. 実際に同じDBの使用を避けられず、複数のチーム/サービスが同じエンティティを必要とするようにサービス境界を分割する場合は、Microserviceチームとデータスキームを担当するチームの間に2つの依存関係を導入します。 )データ形式、b)実際のデータ。これを解決することは不可能ではありませんが、組織にいくらかのオーバーヘッドがあります。また、このような依存関係をあまりにも多く導入すると、開発中に組織が機能不全に陥り、速度が低下する可能性があります。

a)データスキームへの依存性。エンティティのデータ形式は、マイクロサービスの変更を必要とせずに変更できません。これを切り離すには、エンティティデータスキームstrictlyをバージョン管理する必要があり、データベースでは、マイクロサービスが現在使用しているデータのすべてのバージョンをサポートします。これにより、Microservicesチームは、データスキームの新しいバージョンをサポートするためにいつサービスを更新するかを自分で決定できます。これはすべてのユースケースで実行可能ではありませんが、多くのユースケースで機能します。

b)実際に収集されたデータへの依存性収集され、マイクロサービスの既知のバージョンのデータは使用しても問題ありませんが、問題新しいバージョンのデータを生成するサービスがあり、別のサービスがそれに依存している場合に発生します-ただし、最新バージョンを読み取れるようにまだアップグレードされていません。この問題を解決するのは難しく、多くの場合、サービス境界を正しく選択しなかったことを示唆しています。通常、データベース内のデータをアップグレードすると同時に、データに依存するすべてのサービスを展開する以外に選択肢はありません。より奇抜なアプローチは、異なるバージョンのデータを同時に書き込むことです(これは、データが変更可能でない場合にほとんど機能します)。

他のいくつかのケースでa)とb)の両方を解決するには、依存関係をhidden data duplicationおよびeventual consistency。各サービスは、独自のバージョンのデータを保存し、そのサービスの要件が変更された場合にのみ変更することを意味します。サービスは、パブリックデータフローをリッスンすることでこれを実行できます。このようなシナリオでは、イベントベースのアーキテクチャを使用して、イベントを処理し、関連するデータを保存するさまざまなサービスのリスナーがキューに入れて使用できるパブリックイベントのセットを定義します(潜在的にデータの複製を作成します)。現在、他のいくつかのイベントは、内部に保存されたデータを更新する必要があることを示している場合があり、データの独自のコピーを使用して更新するのは各サービスの責任です。このようなパブリックイベントキューを維持する技術は、 Kafka です。

8

理論上の制限

覚えておくべき重要な注意事項の1つは、 CAP定理 :です。

パーティションが存在する場合、一貫性または可用性という2つのオプションが残ります。可用性よりも一貫性を選択すると、ネットワークの分割により特定の情報が最新であることが保証できない場合、システムはエラーまたはタイムアウトを返します。

そのため、特定のエンティティが複数のサービスで一貫していることを「要求」することにより、タイムアウトの問題に対処する必要がある可能性が高くなります。

Akka分散データ

Akkaには、クラスター内で情報を共有するための 分散データモジュール があります。

すべてのデータエントリは、直接複製およびゴシップベースの配布によって、クラスター内のすべてのノードまたは特定の役割を持つノードに分散されます。読み取りおよび書き込みの一貫性レベルをきめ細かく制御できます。

ここには2つの主な勢力がいると思います。

  • デカップリング-それが、そもそもマイクロサービスを持ち、データ永続化に対するシェアードナッシングアプローチを望む理由です
  • 一貫性の要件-正しく理解できれば、最終的な一貫性はすでに十分です

ダイアグラムは私には完全に理にかなっていますが、おそらくユースケース固有の多くのトレードオフが関係しているため、すぐに使用できるフレームワークを知りません。次のように問題にアプローチします。

上に示したように、アップストリームサービスはメッセージバスにイベントを送信します。シリアル化のために、プロデューサーとコンシューマーをあまり結びつけないワイヤー形式を慎重に選択します。私が知っているのはプロトブフとアブロです。新しく追加されたフィールドを気にせず、ローリングアップグレードを実行できる場合は、ダウンストリームを変更することなく、イベントモデルをアップストリームに進化させることができます。

ダウンストリームサービスはイベントをサブスクライブします-メッセージバスはフォールトトレランスを提供する必要があります。このためにkafka=を使用していますが、AMQPを選択したので、必要なものが得られると思います。

ネットワーク障害(ダウンストリームコンシューマーがブローカーに接続できないなど)の場合、可用性よりも(最終的な)一貫性を優先する場合、事前に構成されたしきい値よりも古いことがわかっているデータに依存する要求の処理を拒否することを選択できます。

1

この問題には、サービスコラボレーションとデータモデリングという2つの角度からアプローチできると思います。

サービスコラボレーション

ここでは、サービスオーケストレーションとサービスコレオグラフィーを選択できます。サービス間でのメッセージまたはイベントの交換についてはすでに言及しました。これは、あなたが言ったように動作するかもしれないが、メッセージング部分を扱う各サービスでコードを書くことを含む振り付けアプローチです。ただし、そのためのライブラリがあると確信しています。または、サービス間のデータ更新の管理を担当するオーケストレーターという新しい複合サービスを導入するサービスオーケストレーションを選択できます。データの整合性管理は別のコンポーネントに抽出されるようになったため、ダウンストリームサービスに触れることなく、結果整合性と強力な整合性を切り替えることができます。

データモデリング

また、参加するマイクロサービスの背後にあるデータモデルを再設計し、複数のサービス間で一貫性が必要なエンティティを専用の関係マイクロサービスによって管理される関係に抽出することもできます。このようなマイクロサービスはオーケストレーターに多少似ていますが、一般的な方法で関係をモデル化できるため、カップリングが減少します。

0
clonq