明確な解決策はありません。これは、コンテキストに完全に依存するためです。特に、システムがどの次元にスケーリングされるべきか、実際の問題は何かに依存します。データベースは本当にあなたのボトルネックですか?
この(残念ながらかなり長い)答えは、「マイクロサービスは悪い、一生モノリス!」のようなものですが、それは私の意図ではありません。私のポイントは、マイクロサービスと分散データベースがさまざまな問題を解決できることですが、独自の問題がないわけではありません。アーキテクチャについて強力な議論を行うには、これらの問題が適用されず、軽減できること、およびこのアーキテクチャがビジネスニーズに最適な選択肢であることを示す必要があります。
分散データは困難です。
より優れたスケーリングを可能にする同じ柔軟性は、より弱い保証の裏返しです。特に、分散システムは推論するのがはるかに困難です。
アトミックな更新、トランザクション、一貫性/参照整合性、および耐久性は非常に貴重であり、無意味に放棄すべきではありません。データが不完全、古くなっている、または完全に間違っている場合、データを持つことにはほとんど意味がありません。ビジネス要件としてACIDがあり、そのままでは提供できないデータベーステクノロジー(多くのNoSQLデータベース、またはDB-per-microserviceアーキテクチャなど)を使用している場合、アプリケーションはギャップを埋め、それらの保証を提供する必要があります。
これは不可能ではありませんが、正しく行うのは難しいです。とてもトリッキーです。特に、各データベースに複数のライターが存在する分散設定では。この難しさは、おそらくドロップされたデータ、一貫性のないデータなどを含むバグの可能性が高いことを意味します。
たとえば、Cassandraの分析から始めて、有名な分散データベースシステムのJepsen分析を読むことを検討してください。私はその分析の半分を理解していませんが、TL; DRは、分散システムは非常に困難であり、業界をリードするプロジェクトでさえ、後知恵で明らかなように誤解することがあります。
分散システムは、より大きな開発努力も意味します。ある程度までは、開発コストとより強力なハードウェアでのお金の削減との間には直接的なトレードオフがあります。
例:ぶら下がり参照
実際には、コンピューターサイエンスではなく、ビジネス要件を確認して、ACIDを緩和できるかどうか、どのように緩和できるかを確認する必要があります。例えば、多くの外部キー関係は、見た目ほど重要ではないかもしれません。製品とカテゴリーn:mの関係を考えてください。RDBMSでは、外部キー制約を使用して、既存の製品と既存のカテゴリのみがその関係の一部となるようにします。製品とカテゴリのサービスを別々に導入し、製品またはカテゴリを削除するとどうなりますか?
この場合、それは大きな問題ではない可能性があり、アプリケーションを作成して、存在しない製品またはカテゴリを除外することができます。しかし、トレードオフがあります!
これにはJOIN
、データベースサーバーからアプリケーションに処理を移動するだけの、複数のデータベース/マイクロサービス上のアプリケーションレベルが必要になる場合があることに注意してください。これにより総負荷が増加し、ネットワークを介して余分なデータを移動する必要があります。
これはページネーションを混乱させる可能性があります。たとえば、カテゴリから次の25製品を要求し、その応答から使用できない製品を除外します。これで、アプリケーションに23の製品が表示されます。理論的には、製品がゼロのページも可能です。
関連する各変更の後、または定期的に、ぶら下がり参照をクリーンアップするスクリプトを時々実行する必要があります。このようなスクリプトは、バッキングデータベース/マイクロサービスにすべての製品/カテゴリを要求して、それがまだ存在するかどうかを確認する必要があるため、かなり高価であることに注意してください。
これは明らかなはずですが、明確にするために、IDを再利用しないでください。自動インクリメントスタイルのIDは、問題がある場合とない場合があります。GUIDまたはハッシュは、たとえば、アイテムがデータベースに挿入される前にIDを割り当てることができるなど、柔軟性を高めます。
例:同時注文
代わりに、製品と注文の関係を検討してください。製品が削除または変更された場合、注文はどうなりますか?わかりました。簡単に関連する製品データを注文エントリにコピーして、利用可能な状態に保つことができます。簡単にするためにディスクスペースを取引します。しかし、製品の価格が変更されたり、その製品の注文が行われる直前に製品が利用できなくなったりした場合はどうなりますか?分散システムでは、効果が伝播するのに時間がかかり、古いデータで順序が変わる可能性があります。
繰り返しますが、これにアプローチする方法は、ビジネス要件によって異なります。期限切れの注文は受け入れられる可能性があり、注文が履行できない場合は後でキャンセルできます。
しかし、それはオプションではないかもしれません。例えば、高度な同時設定の場合です。3000人が最初の10秒以内にコンサートチケットを買いに急いでいると考えてください。最後のチケットを複数の人に販売する確率はどのくらいですか?これらの衝突がどのように扱われるかに依存しますが、とポアソン分布を使用してλ = 3000 / (10s / 10ms) = 3
、我々が得るP(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%
10msの間隔あたりの衝突の可能性を。不正行為を行わずに注文の大部分を販売し、後でキャンセルできるかどうかは、法務部門との興味深い会話につながる可能性があります。
プラグマティズムとは、最高の機能を選りすぐることを意味します。
幸いなことに、そうでない場合は、分散データベースモデルに移行する必要はありません。「適切に」マイクロサービスを行わない場合、マイクロサービスクラブの会員資格を取り消すことはできません。そのようなクラブは存在せず、マイクロサービスを構築する真の方法もないからです。
プラグマティズムは毎回勝つため、問題を解決するためにさまざまなアプローチを組み合わせて組み合わせてください。これは、一元化されたデータベースを持つマイクロサービスを意味する場合もあります。本当に、必要がなければ分散データベースの苦痛を経験しないでください。
マイクロサービスなしでスケーリングできます。
マイクロサービスには2つの大きな利点があります。
- 別々のチームが独自に開発および展開できるという組織上の利点(サービスが安定したインターフェイスを提供する必要があります)。
- 各マイクロサービスを個別にスケーリングできる運用上の利点。
独立したスケーリングが必要ない場合、マイクロサービスはあまり魅力的ではありません。
データベースサーバーは、既にリードレプリカを追加するなどして、独立して(ある程度)拡張できるサービスの一種です。ストアドプロシージャに言及します。それらを減らすと、他のスケーラビリティの議論が意味をなさないほど大きな影響を与える可能性があります。
そして、すべてのサービスをライブラリーとして含むスケーラブルなモノリスを持つことは完全に可能です。その後、モノリスのインスタンスをさらに起動することでスケーリングできます。もちろん、各インスタンスをステートレスにする必要があります。
これは、モノリスが大きすぎて合理的に展開できない場合、または一部のサービスに特別なリソース要件があるため、それらを個別にスケーリングする必要がある場合にうまく機能する傾向があります。追加のリソースが関係する問題ドメインには、個別のデータモデルが関係しない場合があります。
強力なビジネスケースはありますか?
組織のビジネスニーズを認識しているため、分析に基づいて、マイクロサービスごとのデータベースアーキテクチャの引数を作成できます。
- 特定の規模が必要であり、このアーキテクチャは、そのようなセットアップおよび代替ソリューションの開発努力の増加を考慮して、そのスケーラビリティを得るための最も費用対効果の高いアプローチです。そして
- 上記のようなさまざまな問題を引き起こすことなく、ビジネス要件により関連するACID保証を緩和できること。
逆に、これを実証できない場合、特に現在のデータベース設計が将来に十分な規模をサポートできる場合(同僚が信じているように思われる場合)、答えもあります。
また、スケーラビリティに大きなYAGNIコンポーネントがあります。不確実性に直面している場合、これはスケーラビリティの構築に関する戦略的なビジネス上の決定です(総コストは低くなりますが、機会コストが含まれ、必要ではない場合があります)スケーラビリティに関する作業を延期します(必要に応じて総コストが高くなりますが、実際のスケールのアイデア)。これは主に技術的な決定ではありません。