web-dev-qa-db-ja.com

マイクロサービスがデータベーステーブルに個別にアクセスしたり、結合されたデータを操作したりする方が良いですか?

マイクロサービスについての私の限られた理解では、彼らはかなり限られた情報のプールに焦点を当てているようであり、おそらく予期されなかった方法ですべてのデータをまとめるのはアプリケーションに任せています。

私は、いくつかの新しいコンセプトを理解するために、簡単なプロジェクトに取り組んでいます。アプリケーションは、本で構成されるライブラリ用です。本には、ID、タイトル、およびいくつかの「持ち物」があります。たとえば、0人以上の著者、0人以上の編集者、0人以上の翻訳者など。

本は1つのテーブルにあり、人々は別のテーブルにあり、関係は3番目のテーブルにあります。

@IdClass(BookAuthorId.class)
public class BookAuthor {
    @Id
    private char type;  //A=Author, E=Editor, T=Trl8r

    @Id
    @JsonProperty("BOOK_ID")
    private Long bookId;

    @Id
    @JsonProperty("AUTH_ID")
    private Long authorId;
}

これらの関係を本のモデルに直接入れることもできますが、著者が別の電話で取り上げられる別のアプローチを考えています。

http://Host/api/book/{bookid}

http://Host/api/book/{bookid}/author
http://Host/api/book/{bookid}/editor
http://Host/api/book/{bookid}/translator

返されたデータは最小限に保たれ、クエリは非常にシンプルに保たれ、データコントラクトの維持がおそらく簡単になるように思えます。

欠点としては、呼び出しの数は増加しますが、クライアントではなくサーバー側ですべての情報をマーシャリングするBackend-for-Frontendレイヤーを使用することでこれを軽減できる可能性があります。

私の単純なプロジェクトでは、どちらの方法でもうまくいくと確信していますが、これらの2つのアプローチが現実の世界でどのように機能するのか疑問に思っています。

  • もう1つスケーラブルですか?
  • 維持するのがもう1つ難しいですか?
  • 絶対に避けるべきですか?
3
paul

ここには誤解があります。マイクロサービスは、「限られたデータプール」で機能するようには設計されていません。

マイクロサービスは、疎結合され、独立して展開およびスケーラブルになるように設計されています。これらの目的をサポートする効果的なパターンは、各マイクロサービスに独自のデータベースを持たせることです。どうして ?

  • 共有データベースはスケーラビリティを制限する可能性があります。
  • 異なるマイクロサービス間で共有データベースを使用すると、dbスキーマを介して依存関係が隠されるリスクが生じる可能性があります

結合を回避することでデータ量を人工的に制限すること(dbは手作りのアルゴリズムよりもはるかに優れている)は、この考慮事項には入りません。

もちろん、別のマイクロサービスに属すべきテーブルについて話す場合、私の答えは異なります。しかし、この場合、私の議論はデータを分離することであり、結合を回避することではありません。ちなみに、テーブルは別のデータベースにあるため、どうしても結合を行うことはありません;-)

これにより、マイクロサービスの細分性の問題が発生します。それが本と本を説明する情報に関するものである場合、これらを人為的な要素に人為的に分割する必要はありません。それが一方の本についてであり、もう一方の人についてである場合(たとえば、著者の追跡、著作権契約の管理などが必要なため)、さまざまなマイクロサービスについて考え始めることができます。この点について、あなたは マイクロサービス分解 に関するChris Richardsonのガイダンスに従うことに興味があるかもしれません:ビジネス能力、サブドメイン、自立型サービス、またはチーム責任。

5
Christophe

その多くは、データベースの設計に基づいたデータのアクセスパターンに依存し、これがマイクロサービスの設計にさらに影響を与えます。

エンティティを垂直に沿って分割することを考えることができます(本、著者、関係を別のテーブルにあるように)。これは、ある意味で自動的に3つの異なるマイクロサービスにつながります。もちろん、より複雑なケースでは、結合と集計のコストは高くなりますが、それは意思決定基準の1つです。本当に多くの結合を必要とする方法でデータにアクセスしますか?その場合は、エンティティではなくビジネス機能に基づいてデータベースを分割することをお勧めします。エンティティが存在する可能性がありますが、前処理された集約ビューからのリクエストに対応します。

もう1つスケーラブルですか?
一般に、基礎となるエンティティが分離されて変更のカスケード効果を最小限にできる分離レベルを作成している限り、スケールの解決ははるかに簡単です。これは、要件の変更が頻繁に発生する動的環境で作業する場合に特に当てはまります。

もう1つはメンテナンスが難しいですか?いずれかの問題を解決する必要があります。エンティティが正規化されていて、複数のテーブルで多くの操作が必要な場合は、アプリケーションが肥大化しています。逆に、アプリケーションの複雑さを軽減しようとすると、データベースが肥大化します。

絶対に避けなければなりませんか?いいえ。それはあなたのために何がうまくいくかという問題です。アプリケーションの種類と複雑さによっては、既存の設計やソリューションが機能しない場合があります(可能性は少なくなりますが、ちょっと..)。この状況は、より多くのパターンとアーキテクチャスタイルが形成されることにつながり、ハードウェアとソフトウェアの新しいソリューションが明らかになります。一般に、採用されたハイブリッドアプローチはソリューションの実現にも役立つ可能性があり、ほとんどの場合、一見最適ではないがはるかに単純な設計が好みに合う可能性があります。

4
skott

これは、マイクロサービスの汎用性に依存することがわかります。

メールを送信するマイクロサービスがあるとします。アドレス、本文、添付ファイルなどのテーブルがたくさんあるかもしれませんが、サービスのユーザーはそれを知りませんし、気にしません。データの単一のblobを送信し、大量のメールを送信することを期待します。

ただし、顧客の注文を管理する別のマイクロサービスがある場合があります。これは、他の多くのシステム、ショップ、ストックルーム、マーケティングなどで使用され、それぞれが異なる方法でデータを使用するため、各データタイプの単純なリストで提供すると、全体的に簡単になります。

たとえば、マーケティングでは顧客のドロップダウンリストが必要であり、ショップでは価格付きの製品のリストが必要です。データのスコープを予測できないため、一般的な形式でデータを提供し、呼び出し元のアプリにデータを統合させる

2
Ewan

「REST AP​​I呼び出しで返されるデータ量は?」という質問に対処するための2つのアイデアとテクニックを次に示します。 REST AP​​IはAPIユーザー向けに設計する必要がある(ユーザーの観点から理解できるようにする)必要があるが、1つのクライアントまたはユースケースに特化してはならない

json:apiは、関連するリソースとその 包括 の強力な概念を導入します。このモデルでは、クライアントが必要とする場合、サーバーは追加データを含めることができます。クエリヒントまたはヘッダーを渡して、この動作を指示することもできます。 json:apiがなくてもこれを行うことができますが、ここで説明されている概念は形式化されています。

GraphQL 次に、呼び出し元がどのフィールドとどの関連アイテムを返すかを指定する概念に移動します。

0
Martin K