マイクロサービスとデータベース結合


112

モノリシックアプリケーションをマイクロサービスに分割している人々にとって、データベースを分解するという難問をどのように処理していますか。私が取り組んだ典型的なアプリケーションは、パフォーマンスと単純さの理由から、多くのデータベース統合を行っています。

論理的に異なる2つのテーブル(境界コンテキストがある場合)があり、そのデータの大容量に対して集約処理を行うことが多い場合、モノリスではオブジェクト指向を避け、代わりにデータベースの標準を使用します。統合されたビューをアプリ層に戻す前に、データベース上のデータを処理するJOIN機能。

データベースではなくAPIを介してデータを「結合」する必要があると思われるマイクロサービスに、そのようなデータを分割することをどのように正当化しますか。

私はSam NewmanのMicroservicesの本を読み、Monolithの分割に関する章で、「外部キーの関係の破壊」の例を挙げています。彼は、API全体での結合の実行が遅くなることを認めていますが、とにかくあなたのアプリケーションは十分に速いです、それが以前より遅いことが重要ですか?

これは少しグリブのようですか?人々の経験は何ですか?API結合を許容範囲内で実行するためにどのようなテクニックを使用しましたか?


2
良い質問です。同じ問題が発生しており、結局マテリアライズされたビューがあり、それに対して結合を行っています。私はそれが好きではありませんが、それはマイクロサービスの課題になると思います。これを行うための正しい方法はありません。デザインを選択するだけです。多くの人が具体化された見方をすることができると言いますが、集計された応答が問題になります。もっと良いものがあったら教えてください。
PavanSandeep

私はこれが古いことを知っていますが、これはgraphqlが解決するものですか?セグメント化された移行についてもこれを調べています。これは、graphqlがこれをシームレスにする方法のようです。
themightybun 2018

ある時点で、独断的であることは進むべき道ではないことを理解する必要があります。GraphQLは、データソースの外部で集計を行う適切な例であり、通常は問題なく機能します。
クリスチャンIvicevic

回答:


26
  • パフォーマンスやレイテンシがそれほど重要ではない場合(そうである必要はありません)、必要な追加データをクエリするために単純なRESTful APIを使用するだけで十分です。異なるマイクロサービスに対して複数の呼び出しを行い、1つの結果を返す必要がある場合は、API Gatewayパターンを使用できます 。

  • Polyglot永続化環境に冗長性を持たせることは完全に問題ありません。たとえば、マイクロサービスのメッセージングキューを使用して、何かを変更するたびに「更新」イベントを送信できます。他のマイクロサービスは必要なイベントをリッスンし、データをローカルに保存します。したがって、クエリを実行する代わりに、特定のマイクロサービスに必要なすべてのデータを適切なストレージに保存します。

  • また、キャッシングについても忘れないでください:) RedisMemcachedなどのツールを使用して、他のデータベースへのクエリを頻繁に行わないようにすることができます。


25
すべての良い提案ですが、それでも合理化するのは難しいと思います。データベースで多くの処理を実行することに慣れているためかもしれません。現在のアプリケーションには、大量のデータを処理して小さな結果セットを返す複雑なストアドプロシージャがあります。マイクロサービスアーキテクチャでは、これらのエンティティを異なる境界コンテキストに分割する必要があると思います。現在のアプローチは醜いことはわかっていますが、すべてのデータをアプリ層に戻して処理することを正当化するのは困難です。おそらく、より非正規化または事前計算された集計ビューが役立つでしょう。
Martin Bayly、2015

1
うん、なるほど。マイクロサービスのアプローチはすべての人に適しているわけではなく、慎重に適用する必要があります。おそらく、小さな変更から始めることができます。
sap1ens 2015

おそらくプログラマStackStackがこの質問をするのにより良い場所だったでしょう:programmers.stackexchange.com/questions/279409/…とタグ付けされた他の質問microservices programmers.stackexchange.com/questions/tagged/microservices
Martin Bayly

9

サービスが他のサービスからの特定の参照データの読み取り専用の複製されたコピーを持つことは問題ありません。

それを考えると、モノリシックデータベースをマイクロサービスにリファクタリングしようとすると(書き換えではなく)、

  • サービスのデータベーススキーマを作成する
  • そのスキーマからバージョン対応*ビュー**を作成して、そのスキーマから他のサービスにデータを公開する
  • これらの読み取り専用ビューに対して結合を行います

これにより、他のアプリケーションを中断することなく、テーブルデータ/構造を個別に変更できます。

ビューを使用するのではなく、トリガーを使用してスキーマ間でデータを複製することも検討します。

これは正しい方向への段階的な進歩であり、コンポーネントの継ぎ目を確立します。RESTへの移行は後で行うことができます。

*ビューを拡張できます。重大な変更が必要な場合は、同じビューのv2を作成し、不要になった古いバージョンを削除します。**またはテーブル値関数、またはSproc。


5

CQRS ---コマンドクエリ集約パターンは、Chris Richardsonによるthiへの答えです。各マイクロサービスが独自のデータモデルを更新し、以前のマイクロサービスからの必要な結合データを含むマテリアライズドビューを更新するイベントを生成します。このMVは、クエリが最適化されたNoSql DBまたはRedisまたはelasticsearchです。この手法により、結果的に一貫性が確保されます。これは間違いなく悪くはなく、リアルタイムのアプリケーション側の結合を回避します。これが答えることを願っています。


2

運用とレポートについて、使用領域のソリューションを分離します。

他のマイクロサービスからのデータを必要とする単一のフォームにデータを提供するように動作するマイクロサービス(これは運用上のケースです)については、API結合を使用する方法が適していると思います。大量のデータを取得するのではなく、サービスでデータ統合を行うことができます。

もう1つのケースは、集計などを行うために大量のデータに対して大きなクエリを実行する必要がある場合です(レポートの場合)。このニーズのために、元のスキームと同様に、共有データベースを維持し、マイクロサービスデータベースからのイベントでそれを更新することを考えます。この共有データベースでは、引き続きストアドプロシージャを使用して、労力を節約し、データベースの最適化をサポートできます。


1

マイクロサービスでは、差分を作成します。たとえば、モデルを読み取ります。たとえば、2つの差分がある場合。境界付きコンテキストと誰かが両方のデータを検索したい場合、誰かが両方の境界付きコンテキストからイベントをリッスンし、アプリケーションに固有のビューを作成する必要があります。

この場合、より多くのスペースが必要になりますが、結合や結合は必要ありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.