次の方法で共有


レート制限を使用して Azure Cosmos DB アプリケーションを最適化する

適用対象: NoSQL MongoDB Cassandra Gremlin Table

この記事では、開発者向けに、Azure Cosmos DB に対する要求をレート制限する方法について説明します。 このパターンを実装すると、ターゲット データベースまたはコンテナーのプロビジョニングされたスループットを超えるワークロードが発生した場合のエラーを減らし、全体的なパフォーマンスを向上させることができます。

Azure Cosmos DB でプロビジョニングされたスループットを超える要求があると、TooManyRequestsTimeoutServiceUnavailable のような一時的な障害が発生する可能性があります。 通常は、容量が使用可能なときにこれらの要求を再試行すると成功します。 ただし、この方法では、コードのエラー パスに従って多数の要求が発生し、一般的にスループットが低下する可能性があります。

コストと時間で測定される最適なシステム パフォーマンスは、クライアント側のワークロード トラフィックとサーバー側のプロビジョニングされるスループットを一致させることで実現できます。

次のシナリオを想定してください。

  • Azure Cosmos DB を 20 K RU/秒でプロビジョニングします。
  • アプリケーションは、それぞれ 10 RU のコストがかかる 10 K のレコードを含むインジェスト ジョブを処理します。 このジョブを完了するために必要な合計キャパシティは 100 K RU です。
  • ジョブ全体を Azure Cosmos DB に送信する場合は、多数の一時的な障害と、再試行する必要がある大量の要求バッファーを想定する必要があります。 この状況は、ジョブに必要な RU の総数 (100 K) がプロビジョニングされた最大 (20 K) をはるかに超えているために発生します。 最大 2 K のレコードはデータベースに受け入れられますが、最大 8 K のレコードは拒否されます。 再試行時に最大 8 K のレコードを Azure Cosmos DB に送信し、そのうち最大 2 K のレコードが受け入れられます。 このパターンでは、10 K のレコードではなく、最大 30 K のレコードが送信されると想定する必要があります。
  • 代わりに、5 秒間にこれらの要求を均等に送信する場合は、各バッチがプロビジョニングされた 20 K 以下であるため、障害が発生せず、全体的なスループットの向上を想定することができます。

一定の時間にわたって要求を分散させるには、コードにレート制限メカニズムを導入します。

コンテナーに対してプロビジョニングされた RU は、複数の物理パーティションで均等に共有されます。 上の例では、Azure Cosmos DB が 2 つの物理パーティションをプロビジョニングした場合、それぞれに 10 K RU があります。

要求ユニットの詳細については、「Azure Cosmos DB の要求ユニット」を参照してください。 ワークロードで消費される RU の数を見積もる方法の詳細については、「要求ユニットの考慮事項」を参照してください。 Azure Cosmos DB のパーティション分割の詳細については、「Azure Cosmos DB でのパーティション分割と水平スケーリング」を参照してください。

手法

レート制限を実装する方法は次のようになります。

  1. 使用する書き込み要求と読み取り要求に関するデータがあるように、アプリケーションをプロファイルします。
  2. すべてのインデックスを定義します。
  3. コレクションに適切な量のデータ (サンプル データ) を設定します。 アプリケーションに通常は数百万のレコードが含まれると予想される場合は、数百万のレコードを設定します。
  4. 代表的なドキュメントを作成し、RU コストを記録します。
  5. 代表的なクエリを実行し、RU コストを記録します。
  6. アプリケーションに関数を実装し、結果に基づいて特定の要求のコストを判断します。
  7. コードにレート制限メカニズムを実装して、1 秒間に Azure Cosmos DB に送信されるすべての操作の合計が、プロビジョニングされるスループットを超えないようにします。
  8. アプリケーションのロード テストを行い、プロビジョニングされたスループットを超過していないことを確認します。
  9. RU コストを定期的に再テストし、必要に応じてコスト関数を更新します。

インデックス作成

使い慣れている他の SQL データベースや NoSQL データベースとは異なり、新しく作成されたコンテナーの Azure Cosmos DB の既定のインデックス作成ポリシーは、すべてのプロパティにインデックスを付けます。 プロパティにインデックスが付けられるたびに、書き込みの RU コストが増加します。

既定のインデックス作成ポリシーでは、読み取り負荷の高いシステムで、クエリのフィルター条件が格納されているすべてのフィールドに適切に分散されている場合は、待機時間が短くなります。 たとえば、エンド ユーザーが作成したアドホック検索の処理に Azure Cosmos DB がほとんどの時間を費やしているシステムでは、メリットがある可能性があります。

検索されないプロパティをインデックス付けから除外することができます。 書き込み負荷が高くレコード取得パターンが制約されているシステムでは、インデックスからプロパティを削除すると、全体的なシステム パフォーマンス (コストと時間) が向上する可能性があります。

コストを測定する前に、実際のケースに適したインデックス ポリシーを意図的に構成する必要があります。 また、後でインデックスを変更する場合は、すべてのコスト計算を再び実行する必要があります。

可能な場合は、通常時およびピーク時の需要条件の一般的なクエリを反映した負荷で、開発中のシステムをテストすると、使用するインデックス作成ポリシーを明らかにするのに役立ちます。

インデックスの詳細については、「Azure Cosmos DB でのインデックス作成ポリシー」をご覧ください。

コストの測定

コストを測定する際には、いくつかの主要な概念があります。

  • 要求ユニットの考慮事項」での説明に従って、RU の使用に影響 を与えるすべての要因を考慮してください。
  • データベースまたはコンテナー内のすべての読み取りと書き込みでは、同じプロビジョニング スループットが共有されます。
  • RU の消費は、使用されている Azure Cosmos DB API に関係なく発生します。
  • コレクションのパーティション戦略は、システムのコストに大きな影響を与える可能性があります。 詳細については、「Azure Cosmos DB でのパーティション分割と水平スケーリング」をご覧ください。
  • 代表的なドキュメントと代表的なクエリを使用します。
    • これらは、運用システムで発生するとものに近いと思われるドキュメントとクエリです。
    • これらの代表的なドキュメントとクエリを取得する最善の方法は、アプリケーションの使用をインストルメント化することです。 常にデータに基づいた判断をすることが最善です。
  • コストを定期的に測定します。
    • インデックスの変更。インデックスのサイズがコストに影響を与える可能性があります。
    • 代表的なドキュメントとクエリの反復可能な (自動化された) テストを作成すると便利です。
    • 代表的なドキュメントやクエリがまだ代表的であることを確認します。

要求のコストを確認する方法は、API によって異なります。

書き込み要求

書き込み操作のコストは、予測しやすい傾向があります。 レコードを挿入し、Azure Cosmos DB によって報告されたコストを記録します。

サイズが異なるドキュメントや、異なるインデックスを使用するドキュメントがある場合は、それらをすべて測定することが重要です。 代表的なドキュメントのコストが近いため、すべての書き込みに 1 つの値を割り当てることができる場合があります。 たとえば、13.14 RU、16.01 RU、12.63 RU のコストが見つかった場合は、それらのコストを 14 RU の平均値することができます。

読み取り要求

クエリ操作のコストは、次のような理由で予測が非常に困難になる可能性があります。

  • システムでユーザー定義クエリがサポートされている場合は、コストを判断するために、受信クエリを代表的なクエリにマップする必要があります。 このプロセスには、次のようなさまざまな形式があります。
    • クエリを正確に一致させることができる場合があります。 直接一致するものがない場合は、最も近い代表的なクエリを見つける必要があります。
    • クエリの特性に基づいてコストを計算できる場合があります。 たとえば、クエリの各句で特定のコストが発生している場合や、インデックスを付けるプロパティのコストが "x" で、インデックスが付けられないプロパティは "y" である場合などがあります。
  • 結果の数は異なる場合がありますが、統計がない限り、戻り値のペイロードからの RU の影響を予測することはできません。

クエリ操作のコストは 1 つではなく、複数の関数でクエリを評価してコストを計算する場合もあります。 NoSQL 用 API を使用している場合は、操作の実際のコストを評価し、見積もりの精度を判断することができます (この推定の調整はコード内で自動的に行われる可能性もあります)。

一時的な障害の処理

レート制限メカニズムを実装している場合でも、次の理由により、アプリケーションは一時的なエラー処理を必要とします。

  • 要求の実際のコストは、予想されるコストとは異なる場合があります。
  • 一時的な障害は、TooManyRequests 以外の理由で発生する可能性があります。

ただし、アプリケーションにレート制限メカニズムを適切に実装した場合は、一時的な障害の数が大幅に減少します。

この記事では、クライアント側の調整とワークロードのバッチ処理について説明しますが、システムの全体的なスループットを管理するために使用できる他の手法もあります。

自動スケール

Azure Cosmos DB で自動スケーリング プロビジョニング スループットを使用すると、お使いのデータベースまたはコンテナーのスループット (RU/秒) を自動的かつ即座にスケーリングできます。 ワークロードの可用性、待機時間、スループット、またはパフォーマンスに影響を与えずに、使用量に基づいてスループットがスケーリングされます。

自動スケーリングのプロビジョニング スループットは、トラフィック パターンが変動し予測できないミッション クリティカルなワークロードに最適であり、ハイ パフォーマンスとスケーリングに対する SLA を必要とします。

自動スケーリングの詳細については、自動スケーリングのスループットを使用した Azure Cosmos コンテナーとデータベースの作成に関するページをご覧ください。

キュー ベースの負荷平準化パターン

クライアントと Azure Cosmos DB の間のバッファーとして機能するキューを導入することで、サービスの障害やタスクのタイム アウトが発生する場合がある断続的な大きい負荷を平準化することができます。

このパターンは、過負荷になる可能性のあるサービスを使用するすべてのアプリケーションに有効です。 しかし、アプリケーションが最短の待機時間でサービスからの応答を予期している場合、このパターンは有効ではありません。

多くの場合、このパターンは取り込み操作に適しています。

このパターンの詳細については、「キューベースの負荷平準化パターン」を参照してください。

キャッシュ アサイド パターン

毎回 Azure Cosmos DB に対してクエリを実行する代わりに、必要に応じてキャッシュにデータを読み込むことを検討することができます。 キャッシュを使用すると、パフォーマンスが向上するだけでなく、キャッシュに保持されているデータと基になるデータ ストアのデータの間で整合性が維持されます。

詳細については、「キャッシュアサイド パターン」を参照してください。

具体化されたビュー パターン

必要なクエリ操作に合わせてデータが最適に書式設定されていない場合は、Azure Cosmos DB にデータを格納した後で、ビューを他のコレクションに事前に設定することができます。 このパターンにより、効率的なクエリとデータ抽出をサポートできるようになり、アプリケーションのパフォーマンスが向上します。

詳細については、「具体化されたビュー パターン」を参照してください

次の手順