web-dev-qa-db-ja.com

マイクロサービス間でのデータの同期

お客様にサービスを提供する2〜3ダースのマイクロサービスがあります。これらのサービスはKubernetesクラスターにデプロイされ、3つまたは4つのAPIゲートウェイを介してのみ外部にアクセスできます。

2つ以上のマイクロサービスで同じデータが必要な場合があることがわかったため、この問題を解決するためのいくつかの戦略を評価し、ソリューションを分割して実装しました。他のデザインと同様に、適切なアプローチを使用しているかどうか、デザインに潜在的な落とし穴がないかどうかは100%わかりません。

ケース1:業務上の重要度の低いサービスServiceLが業務上の重要度の高いサービスServiceHからのデータを必要とする場合、ServiceLServiceHを直接入力して、必要なデータを取得します。

ケース2:ビジネス上の重要性の低いサービスServiceLが多くの重要なサービスからのデータを必要とする場合ServiceH1ServiceH2など)、次にServiceH1ServiceH2そのデータを含むメッセージをRabbitMQに発行します。メッセージのパブリッシュはファイアアンドフォーゲットであるため、サービスはブロックされません。 ServiceLはこれらのメッセージをサブスクライブし、独自のデータストアにデータを保存します。 ServiceLがデータを利用できるようになるまでの遅延は問題ありません。

ケース3:ビジネス上の重要度の高いサービスServiceHがそれほど重要ではないサービスServiceLからのデータを必要とする場合、ServiceLはそれを使用してメッセージを発行しますデータの同期の緊急度に応じて、ファイアアンドフォーゲットまたはブロッキングメカニズムを介してデータをRabbitMQに送信します。 ServiceHはメッセージを消費し、データストアに格納します。多くの場合、データはServiceHがレポートと要約のために必要とするものであり、要約が常に完全に最新でなくてもかまいません(結果的に整合性があります)。

ケース4: 2つのサービスがデータを必要とし、両方がデータを読み取るだけでなく変更する場合も、ドメイン識別が間違っていると考えられます。一つに。

ケース2と3:の追加情報サービス間でデータを同期するためにRabbitMQのようなメッセージングフレームワークを使用すると、ある期間にわたって、データがサービス間で同期しなくなっていることがわかりました。データが同期しなくなると、RabbitMQとリプレイメッセージからの統計を見ることができましたが、これは不必要な複雑さをもたらすと考えています。最終的には、1日1回ジョブを実行して、ソースサービスから宛先サービスにデータを同期しました。データは、該当するサービスから取得され、データストアから直接取得されません。

これはマイクロサービス間でデータを同期する良い方法ですか?落とし穴はありますか?

" Ambrosia "という名前のMicrosoftの新しいプロジェクトコードの1つを見てみます(リンクをクリックすると、プロジェクトがオープンソースで開発されているGithubページに移動します)分散サービスを開発する際に、この正確な問題とその他のいくつかの主要なデータ整合性問題の解決策を提供することに焦点を当てています。

Cliff-notesバージョンは、Virtual Resiliencyを提供することで、次の意味を持っていると説明しています:

仮想復元力は、(おそらく分散された)プログラミングおよび実行環境のメカニズムであり、通常はログを使用します。これは、アプリケーションの再生可能な決定論的な性質とシリアライザビリティを利用して、障害を自動的にマスクします。

Ambrosiaプロジェクトを使用する主な利点の1つは、トランスポート層の信頼性のおかげで発生するすべての一時的な障害処理とデータの整合性の問題の上に抽象化の層が提供されることです。これは、基盤となるAmbrosiaフレームワークが横断的な問題のすべてを管理するため、開発者がコードベースに障害処理またはデータの整合性を書き込む必要がないことを意味します、および切断された接続の再接続の処理(tunnels、sshなど)

以下の情報はすべて、プロジェクトのGithubページから直接取得されているため、上記の最初の段落のリンクをクリックすると、この情報や、はるかに詳細なサンプルユースケースなどを見つけることができます。これが皆さんのお役に立てば幸いです。現在クラウドネイティブコンテキストで実行しているプロジェクトに最適です。


使い方

下の図は、AMBROSIAアプリケーションの基本的なアーキテクチャの概要を示し、Immortalsと呼ばれる2つの通信AMBROSIAサービスを示しています。図の内側の各ボックスは、Immortalの一部として実行される個別のプロセスを表しています。 Immortalの各インスタンスは、アプリケーションプロセス内で実行されるソフトウェアオブジェクトおよび制御スレッドとして存在します。 Immortalインスタンスは、Immortal Coordinatorプロセスを通じて他のImmortalインスタンスと通信します。このプロセスは、インスタンスのRPCを永続的にログに記録し、RPCの送信に必要な低レベルのネットワークをカプセル化します。ログ内のリクエストの位置によって、リクエストが実行のためにアプリケーションプロセスに送信され、リカバリ時に再実行される順序が決まります。 The Ambrosia System Architecture

アンブロシア建築

さらに、言語固有のAMBROSIAバインディングは、状態シリアライザーを提供します。リカバリ中のサービスの開始からの再生を回避するために、Immortal Coordinatorは、アプリケーションの状態を含む、Immortalの状態を時々チェックポイントします。このシリアライゼーションが提供される方法は、言語ごとに、または同じ言語のバインディング間でも異なる可能性があります。

3
Flipurbit

「ビジネスの重要性」と「ビジネスの重要性」の分離は避けます。任意の区別のようであり、外部の理由から変更される可能性があるもののようです-新しいビジネスの焦点、ドメインのより良い理解など-変更が難しいアーキテクチャの決定をあなたに残します。なぜこの分離が存在するのか、そして開発側でそれが何を意味するのか知りたいのですが。

一般に、可能な場合は常にサービス間でRPC /直接呼び出しを優先し、通常はパフォーマンスに関係する特別な場合のためにキューやその他の通信メカニズムを残す必要があります。そして、それらの場合でも、キューでリッスンしている一部のサービスが「ストリーミング」方式で同じことを行うのではなく、派生データの最終的に一貫性のある更新を実行するバックエンドジョブが必要です。キューを使用する際に遭遇した多くの/すべてのケースは、より堅牢な「バックエンドジョブ」で置き換えることができた可能性があります。ただし、Hadoopや派手なものである必要はありません。定期的に実行されるバイナリ/ cronで実行できます。待ち行列とサービスの周りには常に多くの儀式があります。多くの場合、dbへの書き込みがありますandキューへの書き込み。どの書き込みが送信されたかの追跡、失敗した書き込みの調整ジョブ、再試行など、特別な注意が必要です。言うまでもなく、システムについての推論がより困難になり、スーパーハードでローカルにテストを行うことができます。

0
Horia Coman