web-dev-qa-db-ja.com

マイクロサービスアーキテクチャを使用しているときにDBの同期を保つ方法は?

マイクロサービスアーキテクチャのしくみを学習しようとしています。これまでのところ、各マイクロサービスには独自のデータベースが必要であることを理解していません。

それでは、顧客の作成と顧客のリストの返却を担当する顧客マイクロサービスがあるとしましょう。もちろん、サービスには独自の顧客DBがあります。

このサービスに非常に高い負荷がかかっているとしましょう。20倍にスケールアウトすることにしました。

20のマイクロサービスがあり、それぞれに独自のDBがあり、すべてのサービスがロードバランサーの背後にあります。

これで、クライアントは顧客を作成することを望み、ロードバランサはクライアント要求をサービス9/20に送信し、顧客が作成されます。

次の要求では、同じクライアントが顧客が作成されていることを確認し、顧客のリストを表示したい場合、要求でLBはサービス11/20に送信します。

次に、サービス9/20が新しく作成された顧客をサービス11/20のdbに確実に同期するようにするにはどうすればよいですか?

MSSQLには、最初のコミットを下げる前にDBの同期を維持し、最初に他のすべてのデータベースにデータを保存する機能があります。コミットするために取る?

21
Timsen

各マイクロサービスには独自のデータベースが必要です

マイクロサービスごとに個別のDBは必須ではありません(実際には必須ではありません)。

マイクロサービスはいくつでも同じデータベース上で作業できますが、たとえば異なるスキーマを使用できます。

マイクロサービスの境界付きコンテキストが境界でなければなりません。

このサービスの負荷が非常に高いとしましょう。20倍のスケールアウトを選択します。

同じマイクロサービスの(X)インスタンスにスケーリングしても、同じサービスのインスタンスごとに個別のデータベースが必要になるとは限りません。

ほとんどのデータベースは、同時接続、ユーザー、トランザクションを考慮して設計されています。単一のデータベースインスタンス(楽観的な同時実行性がある)は、数百(数千ではないにしても)の同時接続を適切に処理できます。

同じサービスのインスタンスごとに個別のDBを明示的に選択した場合は、それらのデータベースを同期する必要があります。ほとんどの場合、データの整合性が損なわれます。

ここにいくつかの提案があります:

  • 使用しているインスタンスの数に関係なく、マイクロサービスごとに(インスタンスごとではなく)単一のデータベースを使用します。また、単一のDBが負荷を処理できないことが確実な場合にのみ、インスタンスごとにDBを検討してください。

  • DB(おそらくredisキャッシュ)の上部にある共有キャッシュレイヤーを使用する

  • データベースクラスタを使用して、データベースの高負荷/可用性に対処します。

12
Bishoy

複数のサービスに同じデータベースを使用することは可能かもしれませんが、サービス間で望ましいよりも高い結合が作成されるため、これを回避する必要があります。例えば。データベースのダウンタイムは、共有するすべてのサービスに影響しますが、各サービスに独自のサービスがある場合は、1つのサービスにのみ影響します。

(RESTを使用するなど)相互に同期呼び出しを行うサービスの「分散モノリス」を回避するには、ストリーミングベースのアプローチを使用します。各サービスは、データが変更されるたびに変更イベントを発行し、他のサービスはこれらのストリームをサブスクライブできます。そのため、関連するデータ変更に対応できます。ローカルバージョンのデータを(彼らが必要としている列だけなど、彼らのニーズに適した表現で)独自のデータベースに保存する。そうすれば、他のサービスがしばらく利用できない場合でも、機能を提供できます。当然、そのようなアーキテクチャは結果整合性のセマンティクスを採用していますが、通常、分散システムではとにかくそれは避けられません。

このようなデータストリームを設定する1つの方法は、データベースのログファイル(MySQLのbinlogなど)を追跡し、INSERT、UPDATE、DELETEごとに対応するイベントを発行する変更データキャプチャCDCです。オープンソースのCDCツールの1つは Debezium で、これにはMySQL、Postgres、MongoDB、およびOracleおよびSQL Serverのコネクタ(現在作業中)が付属しています。 Apache Kafkaをストリーミングバックボーンとして、またはJavaアプリケーション内のライブラリとして使用して、Pulsarなどの他のストリーミングレイヤーにデータ変更をストリーミングできるようにします。または、わずかなコードでKinesisを使用します。たとえば、Kafkaのように、変更イベントに永続トピックを使用する1つの優れた利点は、新しいトピックが表示され、(トピックの保持ポリシーに応じて)変更ストリーム全体を再読み取りできることです。各レコードの現在の状態を取得して、ローカルデータベースの初期シードを実行します。

(免責事項:私はDebeziumのリーダーです)

3
Gunnar

これは、非同期パラダイムに従ってエンティティの作成と表示を分離するCQRS設計パターンを使用して実現できます。

作成中に、エンティティの永続性をKafka/RabbitMQにプッシュし、それを非同期でデータベースにプッシュします。マテリアライズドビューをDB上に作成できるため、検索が高速になります。

0
DevEmani