Azure Cosmos DB での要求コストを最適化する

適用対象: NoSQL MongoDB Cassandra Gremlin Table

この記事では、読み取りと書き込みの要求が要求ユニットにどのように変換されるか、およびこれらの要求のコストを最適化する方法について説明します。 読み取り操作には、ポイント読み取りとクエリが含まれます。 書き込み操作には、アイテムの挿入、置換、削除、upsert が含まれます。

Azure Cosmos DB では、コンテナー内の項目を操作する豊富なデータベース操作が提供されます。 これらの操作のそれぞれに関連付けられたコストは、操作を完了するために必要な CPU、IO、およびメモリに応じて異なります。 ハードウェア リソースについて考えて管理する代わりに、要求ユニット (RU) を、さまざまなデータベース操作を実行して要求を処理するのに必要なリソースの 1 つの測定単位として考えることができます。

要求の RU 使用量の測定

実際のコストを把握し、最適化の効果を評価するために、要求の RU 使用量を測定することが重要です。 このコスト、Azure portal を使用するか、いずれかの SDK を通じて Azure Cosmos DB から返された応答を調べることによって取り込むことができます。 これを実現する方法の詳細については、「Azure Cosmos DB の要求ユニット使用量を確認する」を参照してください。

データの読み取り: ポイント読み取りとクエリ

Azure Cosmos DB での読み取り操作は、通常、以下のように RU 消費量の観点から、最も実行時間が短く、効率的なものから、実行時間が長く、効率性の低いものの順に並べられます。

  • ポイントの読み取り (1 つの項目 ID およびパーティション キーにおいてキーと値を参照する)。
  • 1 つのパーティション キー内にフィルター句を含むクエリ。
  • 任意のプロパティに対して等値または範囲フィルター句を使用しないクエリ。
  • フィルターを使用しないクエリ。

整合性レベルのロール

厳密または有界整合性制約のいずれかの整合性レベルを使用する場合、すべての読み取り操作 (ポイント読み取りまたはクエリ) の RU コストが 2 倍になります。

ポイント読み取り

ポイント読み取りの RU 使用量に影響を与える (使用される整合性レベル以外の) 唯一の要素は、取得するアイテムのサイズです。 次の表では、1 KB と 100 KB のサイズのアイテムのポイント読み取りの RU コストを示します。

アイテムのサイズ 1 つのポイント読み取りのコスト
1 KB 1 RU
100 KB 10 RU

ポイント読み取り (項目 ID とパーティション キーでのキー/値参照) は最も効率的な種類の読み取りであるため、項目 ID に意味のある値を含めるようにすることで、可能な場合は (クエリではなく) ポイント読み取りで項目を取得できるようにしてください。

Note

NoSQL 用 API では、ポイント読み取りは REST API または SDK を使用してのみ行うことができます。 1 つの項目の ID とパーティション キーをフィルター処理するクエリは、ポイント読み取りとは見なされません。 .NET SDK の使用例については、「Azure Cosmos DB for NoSQL の項目を読み取る」を参照してください。

クエリ

クエリの要求ユニットはさまざまな要因に依存します。 たとえば、読み込まれる/返される Azure Cosmos DB 項目の数、インデックスに対する検索の数、クエリのコンパイル時間などの詳細です。 Azure Cosmos DB では、同じデータに対して実行される同じクエリによって、繰り返しの実行でも常に同じ数の要求ユニットが使用されることが保証されます。 クエリ実行メトリックを使用するクエリ プロファイルでは、要求ユニットがどのように使用されたかを把握できます。

場合によっては、一連の 200 個および 429 個の応答、およびページングされたクエリの実行での変化する要求ユニットが表示されます。これは、クエリが利用可能な RU に基づいて、できるだけ早く実行されるためです。 サーバーとクライアントの間の複数のページ/ラウンド トリップに分割されるクエリの実行が表示される場合もあります。 たとえば、10,000 項目が複数のページとして返され、それぞれ、そのページに対して行われた計算に基づいて課金される場合があります。 これらのページ全体で合計するときに、クエリ全体の場合と同じ数の RU を取得する必要があります。

クエリのトラブルシューティング用のメトリック

クエリ (ユーザー定義関数を含む) によって使用されるパフォーマンスおよびスループットは、ほとんどの場合、関数本体によって異なります。 UDF で費やされるクエリの実行時間と、使用される RU の数を確認する最も簡単な方法は、クエリ メトリックを有効にすることです。 .NET SDK を使用する場合に、SDK によって返されるクエリ メトリックのサンプルを以下に示します。

Retrieved Document Count                 :               1              
Retrieved Document Size                  :           9,963 bytes        
Output Document Count                    :               1              
Output Document Size                     :          10,012 bytes        
Index Utilization                        :          100.00 %            
Total Query Execution Time               :            0.48 milliseconds 
  Query Preparation Times 
    Query Compilation Time               :            0.07 milliseconds 
    Logical Plan Build Time              :            0.03 milliseconds 
    Physical Plan Build Time             :            0.05 milliseconds 
    Query Optimization Time              :            0.00 milliseconds 
  Index Lookup Time                      :            0.06 milliseconds 
  Document Load Time                     :            0.03 milliseconds 
  Runtime Execution Times 
    Query Engine Execution Time          :            0.03 milliseconds 
    System Function Execution Time       :            0.00 milliseconds 
    User-defined Function Execution Time :            0.00 milliseconds 
  Document Write Time                    :            0.00 milliseconds 
  Client Side Metrics 
    Retry Count                          :               1              
    Request Charge                       :            3.19 RUs  

コストのクエリを最適化する場合のベスト プラクティス

コストのクエリを最適化するときに、次のベスト プラクティスについて検討してください。

  • 複数のエンティティ型を併置する

    1 つまたは少数のコンテナー内に複数のエンティティ型を併置してみます。 この方法では、価格の観点からだけでなく、クエリの実行やトランザクションについても利点が得られます。 クエリのスコープは 1 つのコンテナーとなります。ストアド プロシージャ/トリガーを介した複数レコードに対するアトミック トランザクションのスコープは、1 つのコンテナー内のパーティション キーとなります。 同じコンテナー内のエンティティーを併置することで、ネットワークのラウンド トリップ数を減らして、レコード全体の関係を解決することができます。 したがって、エンド ツー エンドのパフォーマンスが向上し、大規模なデータセットの複数のレコードに対するアトミック トランザクションが有効になり、その結果、コストが低くなります。 ご自分のシナリオでは 1 つまたは少数のコンテナー内に複数のエンティティ型を併置するのが難しい場合は (通常は、既存のアプリケーションを移行し、コードを変更したくないため)、データベース レベルでのスループットのプロビジョニングを検討する必要があります。

  • 測定と調整によって 1 秒あたりの要求ユニットの使用量を削減する

    クエリの複雑さは、操作で使用される要求ユニット (RU) の数に影響します。 述語の数、述語の特性、UDF の数、ソース データ セットのサイズ。 これらすべての要因がクエリ操作のコストに影響します。

Azure Cosmos DB では、プロビジョニング済みスループット モデルを使用して、スループットと待機時間の観点から予測可能なパフォーマンスを提供します。 プロビジョニング済みスループットは、1 秒あたりの要求ユニット (RU/秒) で表されます。 要求ユニット (RU) は、要求を実行するために必要な CPU、メモリ、IO などのコンピューティング リソースを介した論理抽象化です。 プロビジョニング済みスループット (RU) は確保され、ご使用のコンテナーまたはデータベース専用として、予測可能なスループットおよび待機時間を提供します。 プロビジョニング済みスループットにより、Azure Cosmos DB は予測可能で一貫したパフォーマンスを提供でき、どのような規模でも待機時間の短縮と高可用性が保証されます。 要求ユニットは、アプリケーションに必要なリソースの数に関する推論を簡素化する、正規化された通貨を表します。

要求ヘッダーで返される要求使用量は、特定のクエリのコストを示します。 たとえば、クエリで 1 KB の項目が 1000 個返された場合、操作のコストは 1000 となります。 そのため、後続の要求をレート制限する前に、サーバーは 1 秒以内にこのような要求を 2 つだけ受け付けます。 詳細については、要求ユニットに関する記事と要求ユニット計算ツールのページを参照してください。

データの書き込み

項目を書き込む RU コストは、次のものに依存します。

インデックスを作成せずに 1 KB の項目を挿入すると、約 5.5 RU のコストがかかります。 項目を置換するには、同じ項目を挿入するのに必要な使用量の 2 倍のコストがかかります。

書き込みの最適化

書き込み操作の RU コストを最適化する最善の方法は、項目のサイズと、インデックスを作成するプロパティの数を適正化することです。

  • 非常に大きな項目を Azure Cosmos DB に格納すると、高い RU 使用量が発生し、アンチパターンと見なすことができます。 特に、クエリを実行する必要がないバイナリ コンテンツや大量のテキストを格納しないでください。 ベスト プラクティスとして、この種類のデータを Azure Blob Storage に配置し、Azure Cosmos DB に書き込む項目に、この BLOB への参照 (またはリンク) を格納することをお勧めします。
  • クエリによってフィルター処理されるプロパティのみにインデックスを作成するようインデックス作成ポリシーを最適化すると、書き込み操作によって使用される RU が著しく改善されます。 新しいコンテナーを作成すると、既定のインデックス作成ポリシーによって、項目内のすべてのプロパティのインデックスが作成されます。 これは開発アクティビティに適した既定の設定ですが、運用環境に移行するとき、またはワークロードが大量のトラフィックを受信し始めるときに、インデックス作成ポリシーを再評価およびカスタマイズすることを強くお勧めします。

データの一括インジェストを実行する場合は、このような操作の RU 消費を最適化するように設計されているため、Azure Cosmos DB の Bulk Executor ライブラリを使用することもお勧めします。 必要に応じて、同じライブラリ上に構築された Azure Data Factory を使用することもできます。

次のステップ

次は、先に進み、以下の各記事で Azure Cosmos DB でのコストの最適化の詳細について学習することができます。