1. 序章

マイクロサービスアーキテクチャは絶えず成長しています。 これは、特に廃止されたモノリスアーキテクチャに比べて多くの利点をもたらします。 一方、マイクロサービスを使用してプロジェクトを開発する際には、複数の課題があります。 最も重要な懸念事項の1つは、データベースの設計です。 データ設計に関しては、2つの重要な質問があります。 データを整理する方法とそれを保存する場所は?

このチュートリアルでは、それらに答えようとします。

2. サービスごとのデータベース

マイクロサービスアーキテクチャを使用するときにデータベースを整理するには、主に2つのオプションがあります。

  1. サービスごとのデータベース
  2. 共有データベース

このセクションでは、最初のものについて説明します。

2.1. 基礎

定義上、マイクロサービスは、開発と展開の観点から、緩く結合され、スケーラブルで、独立している必要があります。 したがって、サービスごとのデータベースは、これらの要件を完全に満たすため、推奨されるアプローチです。 それがどのように見えるか見てみましょう:

アイデアは単純です。 各マイクロサービスには、独自のデータストア(スキーマ全体またはテーブル)があります。 他のサービスは、所有していないデータストアにアクセスできません。 このようなソリューションには多くのメリットがあります。

まず、個々のデータベースへの変更は他のサービスに影響を与えません。 したがって、アプリケーションに単一障害点はありません。 いわば、アプリケーションはより弾力性のあるです。

第二に、個々のデータストアはスケーリングが簡単です。 さらに、ドメインのデータはマイクロサービス内にカプセル化されます。 したがって、データ全体でサービスを理解しやすくなります。 これは、開発チームの新しいメンバーにとって特に重要です。 彼らが責任のある分野を完全に理解するのにかかる時間と労力は少なくなります。

最後に、サービスごとのデータベースを使用すると、ポリグロットの永続性を使用できます。 これは、さまざまなマイクロサービスにさまざまなデータベーステクノロジーを使用できることを意味します。 したがって、あるサービスはSQLデータベースを使用し、別のサービスはNoSQLデータベースを使用する場合があります。 この機能により、サービス要件と機能に応じて最も効率的なデータベースを使用できます。

2.2. 欠点

これらすべての利点にもかかわらず、サービスごとのデータベースアプローチに関していくつかの重大な欠点と課題があります。 前述したように、各マイクロサービスは独自のデータストアにのみ直接アクセスできます。 したがって、サービスにはデータを交換するための通信方法が必要です。 したがって、各サービスは明確なAPIを提供する必要があります。

したがって、通信に障害が発生した場合の障害保護メカニズムが必要です。 サービスAからサービスBに支払い要求を送信するとします。 サービスAは、結果に基づいて適切なアクションを実行するための応答を待機します。 その間、サービスBはオフラインになります。 状況を処理し、Bがオンラインに戻ったときに結果をサービスAに通知する必要があります。 サーキットブレーカーメカニズムがここで役立ちます。

次の重要な問題はトランザクションです。 マイクロサービス間でトランザクションをスパンすると、一貫性と原子性に悪影響を与える可能性があります。 同様の欠点は、複雑なクエリに関連しています。 複数のデータストアで結合クエリを実行する簡単な方法はありません。

最後に、マイクロサービスにまたがるデータ関連の操作は、問題が発生した場合にデバッグするのが難しい場合があります。

3. 共有データベース

共有データベースはアンチパターンと見なされます。 しかし、それは議論の余地があります。 重要なのは、共有データベースを使用すると、マイクロサービスはそのコアプロパティであるスケーラビリティ、復元力、および独立性を失うということです。 したがって、共有データベースがマイクロサービスで使用されることはめったにありません。

共有データベースがマイクロサービスプロジェクトに最適なオプションであると思われる場合、マイクロサービスが本当に必要かどうかを再考する必要があります。 たぶん、モノリスがより良い選択でしょう。 共有データベースのアプローチがどのように見えるかを見てみましょう。

マイクロサービスで共有データベースを使用するユースケースは一般的ではありません。 例として、モノリスをマイクロサービスに移行する際の一時的な状態が考えられます。 サービスごとの共有データベースの主な利点は、トランザクション管理です。 トランザクションをサービスにまたがる必要はありません。

さらに、データは完全に制約されており、適切な放射線が保持されます。 その後、冗長性が低下します。 結合を使用すると、複雑なクエリを簡単に実行できます。

もう1つの重要なことは、マイクロサービス間で保存されたデータを交換する必要がないことです。 そのため、APIが簡素化され、通信に失敗した場合のデータと状態の整合性に問題はありません。 ただし、いくつかの重大な欠点があります。

共有データベースを使用するマイクロサービスは簡単に拡張できません。 さらに、データベースは単一障害点になります。 データベースに関連する変更は、複数のサービスに影響を与える可能性があります。 さらに、マイクロサービスは同じデータベースに接続して操作するため、開発と展開の点で独立していません。

このパターンは、次のような場合に考慮することができます。

  • 既存のデータストアを保持する必要があります
  • 既存のデータレイヤーコードベースは変更しないでください
  • トランザクションはアプリケーションにとって非常に重要です

4. データ関連のパターン

マイクロサービスアーキテクチャ内のデータを管理するために使用されるさまざまなパターンがあります。 このセクションでは、重要なものを簡単に紹介します。

4.1. 佐賀パターン

マイクロサービス間でトランザクションをスパンすることは問題になる可能性があることを前述しました。 簡単に言うと、トランザクションは、関連するすべてのサービスが独自の部分を正常に実行した場合にのみ成功します。 1つのサービスで障害が発生した場合、トランザクション全体が失敗するはずです。 さらに、その場合、すでにその役割を果たしているサービスは変更をロールバックする必要があります。

一般に、これがsagaパターンの原因です。 Sagaパターンは、単一の分散トランザクションを表す一連のローカルトランザクションです。 各サービスはローカルトランザクションを実行します。 ローカルトランザクションが正常に終了すると、シーケンス内の次のローカルトランザクションをトリガーするイベントまたはメッセージが公開されます。 失敗した場合、sagaは変更をロールバックする補償トランザクションを提供します。

佐賀パターンの実装には2つのタイプがあります。

  • オーケストレーション–中央コントローラー(オーケストレーター)がマイクロサービス間のすべての対話を管理します
  • コレオグラフィー–イベントを放送する分散型テクニック

4.2. CQRS

CQRS(Command Query Responsibility Segregation)は、別の重要な機能である複数のデータストアからの関連データのクエリに役立ちます。 さらに、関心の分離により、ビジネスロジックの複雑さを簡素化します。 さらに、マイクロサービスのスケーラビリティに役立ちます。

アイデアは単純です。 データレイヤーをビジネスロジックレイヤーから分離しています。 さらに、クラスはデータベースへの書き込み(コマンド)またはデータベースからの読み取り(クエリ)のみを実行できます。 したがって、1つのクラスで両方を実行することはできません。 そのアプローチは多くの利点をもたらします。 コードはより明確で、保守または拡張が容易です。 さまざまなコンポーネントを個別に最適化、開発し、特に重要なものをスケーリングすることができます。

その後、コンポーネントは緩く結合され、作業を開発者またはチーム間で効果的に分割できます。 最後に、コンポーネントに分割されたアプリケーションはテストが簡単です。 CQRSパターンを実装する正しい方法は1つではありません。 実装は、ドメイン、要件、フレームワーク、プロジェクトの実際の状態などに基づくことができます。 CQRSは、イベントソーシングパターンと一緒に使用されることがよくあります。 それについて説明しましょう。

4.3. イベントソーシング

最新のアプリケーションの多くは、さまざまな目的でイベントに依存しています。 たとえば、前述したように、sagaシーケンスのサービスはデータベースをアトミックに更新し、イベントまたはメッセージを公開します。 イベントソーシングは、アプリケーションイベントを利用します。

イベントソーシングは、状態を変更するイベントを永続化することによって状態を表す手法です。 事業体が変更されるたびに、イベントはイベントストアに保持されます。

名前が示すように、イベントサイトはイベントのデータベースです。 SQL、NoSQL、またはプロジェクトに適したその他の方法を使用できます。 さらに、イベントストアはメッセージブローカーとして機能できます。 関心のあるすべてのコンポーネントがサブスクライブします。 イベントが永続化されると、イベントストアはすべてのサブスクライバーに情報を配信します。 イベントの公開は単一のアトミック操作です。 したがって、マイクロサービス全体でデータベース操作の信頼性と原子性を提供します。

さらに、完全な監査ログを作成します。 問題やバグが発生した場合は、状態の変化を調べて、最終的に有効な状態を復元するのは簡単です。 したがって、デバッグはそれほど複雑ではありません。 さらに、イベントソーシングは、オブジェクト指向データとリレーショナルデータの間のインピーダンスの不一致を回避できます。 要約すると、イベントソーシングは、マイクロサービスアーキテクチャまたはイベント駆動型アプリケーションで非常に役立ちます。

5. データベースの選び方は?

マイクロサービスでデータベース設計を計画する際の最初のステップは、モデルを選択することです。 サービスごとのデータベースと共有データベースモデルについてはすでに説明しました。 また、彼らの長所、短所、および一般的なユースケースを検討しました。

2番目のステップは、プロジェクトまたはサービスに最も効率的な特定のデータベーステクノロジを選択することです。 そのためには、いくつかのプロパティを考慮する必要があります。

最初の重要なパラメータは読み取りパフォーマンスです。 読み取りパフォーマンスは、1秒あたりの操作数またはフェッチクエリの速度のいずれかです。 電子商取引、CRM、銀行ソフトウェアに関連するアプリケーションまたはサービスには、通常、データを高速かつ頻繁にフェッチする必要がある機能が含まれています。

2番目に重要なプロパティは、書き込みパフォーマンスです。 前のものと似ています。 ただ、その場合、データベースからの読み取りではなく、データベースへの書き込みを行っています。 サービスが大量のデータを保持する必要がある場合、または大きなBLOBを格納する必要がある場合は、これがコアパラメーターになる可能性があります。

次はレイテンシーです。 これは、ユーザーのアクションとサーバーの応答の間の遅延です。 これは、ユーザーエクスペリエンス関連のコンポーネントで特に重要です。 良い例は、ライブストリーミングアプリケーションやリアルタイムゲームです。

もう1つの重要な特性は、リソース効率です。 通常、消費されるリソースは少ないほど良いです。 プラットフォームによっては、実行が速くなり、ホストの負荷が減り、最終的にはコストがかかる可能性があります。

最後になりましたが、プロビジョニングの効率を考慮する必要があります。 一般に、データベースがマイクロサービスの開発、デプロイ、テストにどのように影響するかを示します。 すでに述べたように、これらの用語でのマイクロサービスの独立性は非常に重要です。

5.1. SQLと NoSQL

ほとんどの場合、プロジェクトまたはサービスで考慮されるテクノロジーには、SQLとNoSQLの2つがあります。 基本的に、特にNoSQLに関しては、より複雑です。 さまざまなNoSQLデータベースの実装があります。 ただし、この記事では、データベースの低レベルの実装については詳しく説明しません。 一般的なSQLとNoSQLを比較してみましょう。

6. 結論

この記事では、マイクロサービスアーキテクチャでのデータベース設計について詳しく説明しました。 ご覧のとおり、非常に複雑な作業です。 すべての要素は慎重に計画され、プロジェクトの効率を最大化するためのプロジェクトのニーズに適合している必要があります。