マイクロサービスでは、サービスごとに単一のデータベースまたは単一のデータベースインスタンスですか?


50

マイクロサービスアーキテクチャの各サービスには独自のデータベースが必要であることを理解しています。しかし、独自のデータベースを持つということは、実際には、同じデータベースインスタンス内に別のデータベースを単に持つことを意味しますか、それとも文字通り別のデータベースインスタンスを含むことを意味しますか?

これにより、私はデータベースの共有を意味するのではなく、これはノー・ノーであり、むしろデータベースのインスタンスです。

たとえば、AWSを使用していて3つのサービスがある場合、単一のRDSインスタンスで各サービスに3つのデータベースを作成しますか、3つのサービスのそれぞれで独立して使用されるデータベースを含む3つのRDSインスタンスを作成しますか?

単一のRDSインスタンスで複数のデータベースを使用することをお勧めする場合、次の理由により、独立したサービスを持つという目的を無効にします。

  1. RDSインスタンスのリソースはサービス間で共有されます。特定の時間にデータベースの使用量が多い可能性のあるサービスAは、同じRDSインスタンス上で異なるデータベースを使用するサービスBに影響しますか?

  2. すべてのサービスは、そのRDSインスタンスのデータベースバージョンに依存します。


8
それはあなたの特定の要件に最適なものです。
ロバートハーベイ

1
自分を「マイクロサービス」の専門家と呼ぶかどうかはわかりませんが、セットアップやデータベースの方法は何でもかまいません。あるサービスによって読み取られ、別のサービスによって書き込まれるdbを持つことができます。または、システム全体で1 db(または技術的にそれ以下)しか使用できません。
マークロジャース

ここで問題には良い読み取りだ:plainoldobjects.com/2015/09/02/...
RandomUs1r

「単一責任の原則」についてお読みください。他のマイクロサービスが使用する「データベースマイクロサービス」の実装について考えたことはありますか?
ChuckCottrill

回答:


20

スケーラビリティ要件と、単一の結果を提供するためにマイクロサービスインスタンスがどのように/どのように協力する必要があるかによります。トレードオフが何であるかを知ることは役立ちます:

すべてを1つのデータベースに保持する

  • 簡単な構成
  • サービスの他のインスタンスとの調整や通信は必要ありません
  • データセット全体を簡単に発見
  • データベースのパフォーマンスによって制限されるシステムパフォーマンス

データベースを分離する

  • リクエストに対する完全な回答は、マイクロサービスインスタンス全体に広がる可能性があります
  • その場合、リクエストを解決するためのコミュニケーションと交渉を増やしました
  • そのマイクロサービスノードを失ったときのデータの処理(データベースがまだ稼働している場合でも、適切な構成の新しいノードがバックアップされるまで、データにアクセスすることはできません)
  • 構成の複雑さの増加

あなたが解決している問題は何ですか?

場合によっては、一時データのみが心配になります。データベースがダウンしても、大きな問題ではありません。そのような場合、データベースを最初から必要としないかもしれません。すべてをメモリに保存し、物事を非常に高速にします。これが最も簡単なソリューションです。

また、データの整合性が必要な場合もありますが、データベースはノードの数に基づいて容量を拡張できます。この場合、おそらく単一のデータベースで十分であり、その応答性を個別に管理することが正しい答えです。

間にいくつかのケースがあります。たとえば、地域固有のデータベースがある場合、異なる地域のサービスのインスタンスごとに個別のデータベースがあります。通常、シャーディングデータベースは地域間でうまく機能しないため、これはデータを少しローカライズし、自分で調整を制御する方法です。

教義と現実

マイクロサービスとそれらがどのようにモジュール化されるべきかに関する多くの記事を読みました。推奨事項は、フロントエンド、マイクロサービス、およびデータ層をユニット全体として保持することから、すべてのインスタンスのデータベースやフロントエンドコードを共有することまで多岐にわたります。通常、分離度を上げると最大のスケーラビリティが得られますが、複雑さが増すという犠牲が伴います。

マイクロサービスの計算が重い場合は、必要に応じてこれらのマイクロサービスの数をスケールできるようにすることは理にかなっています。データベースを共有したり、フロントエンドコードでさえ、このアプローチを傷つけたり、妨げたりすることはありません。

現実には、プロジェクトの特定のニーズには、タイムリーに作業を完了し、測定中のシステム負荷を処理するために(さらに少し)さまざまな妥協が必要になります。完全に分離されたフロントエンド、マイクロサービス、およびデータ層のトリオを高い目標と考えてください。システムへの要求が多いほど、その目標に近づく必要があるでしょう。私たちは全員[insert name of highly successful web entity here]ではありません。彼らは現在の場所から始めませんでした。時には、完璧ではない状況から始めて、それで満足する必要があるだけです。


71

同じ種類のDBシステムとバージョンを使用できるサービスがあると仮定すると、異なるデータベースまたはdbインスタンスを使用する場合、設計時に行う必要のない決定です。代わりに、展開時に決定を行うことができる必要があります。これは、単に構成できるものです。他のサービスのデータベースがホストされている場所にとらわれないようにサービスを設計します。

操作中、1つのインスタンスから開始できます。システムが正常に機能する場合は、そのままにしておきます。ただし、1つのインスタンス上の異なるデータベースがあまりにも多くのリソースを共有しているため、これがシステムに対して適切にスケーリングしないことに気付いた場合、異なるインスタンスを使用するオプションが常にあります。

したがって、2つのリソースを共有させたからといって、サービスがマイクロサービスアーキテクチャに違反することはありません。リソースの共有が必須になったときに違反します。


この種の音は時期尚早の最適化のようです。消費されたリソースが追加インスタンスに値しない場合はどうなりますか?その後、柔軟性を構築する時間を無駄にしました
レゲエギタル

5
@reggaeguitar:これのコストは通常​​無視できるはずです-実際、マイクロサービスアーキテクチャの場合、各サービスのデータベースの場所を個別に構成できるようにするよりも、異なるサービス間でデータベース構成を集中化しようとする方が労力がかかる場合があります。さらに、マイクロサービスアーキテクチャのポイントは高いスケーラビリティです。必要ない場合は、最初にマイクロサービスを決定すべきではありません。
Doc Brown

1
@DocBrownそれは理にかなっています、応答に感謝します!
レゲエギタル

13

関係ありません。

理論的に問題になる唯一のシナリオは、1つのサービスがデータベースの異なるバージョンに移行する必要がある場合です。しかし、それでも、最初から別々のインスタンスを使用することと、その1つのサービスを共有インスタンスから別のサービスに移行することとの間に実際の違いはありません。実際、このシナリオのためだけに別々のインスタンスを持つことは、YAGNIの例だと思います。


1
特定のサービスが単一のRDSインスタンスで頻繁に使用されている場合、そのインスタンスのリソースを使い果たし、その同じRDSインスタンスを使用している他のサービスに影響を与えますか?
キセノン

1
@xenon:はいすべて単独で。オーバーロードされたサービスが他のサービスに影響してはならないという特別な要件があると思いますが。実際、一部のRDSでは、ユーザーごとにリソースの上限を定義することで、単一インスタンスでそれを許可する場合があります。
マイケルボルグ

重要なシナリオは、マイクロサービスインスタンスに独自の状態がある場合です。そして、それは、独自に展開する必要があるインスタンスも、パフォーマンスのボトルネックになることがありデシベル、
ユアン・

3

RDSインスタンスは単一のボックスです。単一のインスタンスに複数のデータベースがある場合、それらはCPU /メモリなどを共有します。

マイクロサービスのパフォーマンスがデータベースのパフォーマンスに制約されている場合:マイクロサービスの複数のコピーをデプロイし、それぞれ異なるデータベースを使用しますが、各データベースを同じRDSインスタンスに配置します。無意味*(フェイルオーバーを除く)。マイクロサービスクラスターは、単一のマイクロサービスと同じ速度で実行されます

ただし、データベースのパフォーマンスに制約されるマイクロサービスは珍しいと言えます。

通常、マイクロサービスはdbからデータを取得し、ロジックを実行し、データベースに情報を書き戻します。パフォーマンスのボトルネックは、選択や挿入ではなくロジックです。

この場合、単にすべてのマイクロサービスインスタンスで同じデータベースを共有できます


ロジックはデータベースではなくボトルネックであるというあなたの主張に疑問を持たなければなりません。私の経験では、パフォーマンスの改善を見つける可能性最も高い場所はデータベースです。
ラバーダック

うーんはい、しかし確かにこれらのパフォーマンスの改善は、dbからサービスにロジックを移動することによって達成されます。それを行うと、THENロジックがボトルネックになります
ユアン

1
通常、いいえ。これらの改善は、インデックスとクエリのチューニングからもたらされます。
ラバーダック

まあ、それは私の経験では珍しいケースに該当します。通常、これらの改善の余地はないということではありませんが、本当に悪いものを削除した後でも、データベースは依然として制限要因です。
ユアン

1

データベースをサービス専用にする目的は、カプセル化です。マイクロサービスは、システム内の他のサービスがパブリックインターフェイスを介して使用するブラックボックスです。

このカプセル化が機能する2つのプレーンがあります。

  • 最初は、アプリケーションレベルでの論理です。サービスはシステム内のいくつかのビジネスオブジェクトを所有しており、これらのオブジェクトに関する状態を保持する必要があります。いくつかのことを、特定のデータベースがこれらのビジネスオブジェクトをバックアップすることは、単に実装の詳細です。別のデータベースを保持することにより、他のサービスが実装にバックドアアクセスすることを防ぎ、代わりにパブリックインターフェイスを使用するように強制します。ここでの目標は、クリーンなアーキテクチャと規律あるプログラミングです。データベースが存在する場所は、このレベルでは関係ありません。ただし、サービスに適切な接続の詳細があり、それを見つけられる限りです。

  • 2番目のレベルは動作可能です。設計が完全なブラックボックスであっても、指摘するように、1台のマシンに配置されたさまざまな作業がリソースを奪い合う場合があります。これは、別個の論理データベースを別個のマシンに配置する正当な理由です。他の回答が指摘しているように、ニーズがそれほど厳しくなく、予算が厳しい場合、これは単一のマシンでのコロケーションの実用的な議論です。ただし、いつものように、トレードオフ:このセットアップでは、システムの成長に応じてより多くのベビーシッターが必要になる場合があります。予算が許せば、1つの大きなマシンを共有するよりも、2つのタスクを実行するために、2つの別々の小さなマシンをほぼ常に好みます。


1

ここでもう少し理論的になると役立つと思います。マイクロサービスの背後にある動機付けのアイデアの1つは、シェアードナッシング、メッセージパッシングプロセスです。マイクロサービスは、アクターモデルのアクターのようなものです。つまり、各プロセスは独自のローカル状態を維持し、1つのプロセスが別のプロセスの状態にアクセスする唯一の方法は、メッセージを送信することです(さらに、他のプロセスはそれらのメッセージが好きでも応答できます)。「すべてのマイクロサービスが独自のデータベースを持っている」とは、プロセス(マイクロサービス)の状態がローカルプライベートであることを意味します。大部分は、これは「データベース」を連結する必要があることを示唆していますつまり、「データベース」はマイクロサービスと同じ論理ノードで保存および実行する必要があります。マイクロサービスの異なる「インスタンス」は個別のプロセスであるため、それぞれ独自の「データベース」を持つ必要があります。

この観点から、グローバルデータベースまたはマイクロサービス間で共有されるデータベース、またはマイクロサービスのインスタンスでさえ、共有状態を構成します。マイクロサービスの観点からこれを処理する「適切な」方法は、「データベース」マイクロサービスによって共有データベースを仲介することです。データベースの内容を知りたい他のマイクロサービスは、その「データベースマイクロサービス」にメッセージを送信します。これは通常、元のマイクロサービスのローカル状態(つまり、マイクロサービスインスタンスごとの「データベース」)の必要性を排除しません!変更されるのは、そのローカル状態が表すものです。「ユーザーサリーは管理者です」を保存する代わりに、「データベースマイクロサービスは5分前に「ユーザーサリーは管理者です」と言った」を保存します。言い換えると、 他のマイクロサービスの状態について。

この利点は、各マイクロサービスが自己完結型であることです。これにより、マイクロサービスは障害のアトミック単位になります。(ほとんど)部分的に機能している状態のマイクロサービスについて心配する必要はありません。もちろん、問題はマイクロサービスのネットワークに移されました。マイクロサービスは、他のマイクロサービスに接続できないため、目的の機能を実行できない場合があります。ただし、メリットは、マイクロサービスが明確に定義された状態になり、古くなった信念を排除するなどして、劣化したサービスや限定的なサービスを提供できる可能性があることです。欠点は、システム全体の一貫したスナップショットを取得することが非常に難しく、非常に多くの(望ましくない)冗長性と複製が発生する可能性があることです。

もちろん、OracleのインスタンスをすべてのDockerコンテナに固定することは推奨されていません。まず、すべてのマイクロサービスに「データベース」が必要なわけではありません。一部のプロセスは、正常に機能するために永続状態を必要としません。たとえば、2つのプロトコル間で変換するマイクロサービスは、必ずしも永続的な状態を必要としません。永続的状態が必要な場合、「データベース」という言葉は「永続的状態」の単なる言葉です。JSONを含むファイル、またはSqliteデータベース、または必要に応じてローカルで実行されるOracleのコピー、またはその他のローカルの手段を使用できます。データを永続的に保存します。「データベース」がローカルでない場合、純粋なマイクロサービスの観点からは、別個の(マイクロ)サービスのように扱う必要があります。このため、RDSインスタンスをマイクロサービスの「データベース」にすることは意味がありません。繰り返しますが、視点は「独自のRDSデータベースを持つマイクロサービスの束」ではなく、「RDSデータベースと通信するマイクロサービスの束」です。この時点で、データが同じデータベースインスタンスに保存されているかどうかに違いはありません。

実際には、マイクロサービスアーキテクチャは非常に複雑になります。この複雑さは、部分的な障害に真剣に対処するだけの代価です。多くの人にとって、利益に見合う価値がないのは行き過ぎです。最も有益と思われる方法でシステムを自由に設計してください。シンプルさと効率性に関する懸念が、純粋なマイクロサービスアーキテクチャからの逸脱につながる可能性は十分にあります。コストは追加のカップリングであり、サービス間の見えない相互作用や、自由に展開および拡張する自由の制限など、独自の複雑さをもたらします。


「他のマイクロサービスに接続できないため。」-私は、マイクロサービスが他のマイクロサービスに連絡するべきではないと考えましたか?
マーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.