Important
これは Azure Cosmos DB 用の最新の Java SDK では "ありません"。 プロジェクトを Azure Cosmos DB Java SDK v4 にアップグレードしてから、Azure Cosmos DB Java SDK v4 のパフォーマンスに関するヒント ガイドをお読みください。 アップグレードするには、 Azure Cosmos DB Java SDK v4 への移行 ガイドと Reactor vs RxJava ガイドの手順に従ってください。
これらのパフォーマンスのヒントは、Azure Cosmos DB Sync Java SDK v2 のみを対象としています。 詳細については、 Maven リポジトリ を参照してください。
Important
2024 年 2 月 29 日に、Azure Cosmos DB Sync Java SDK v2.x は廃止されます。SDK と SDK を使用するすべてのアプリケーション は引き続き機能します。Azure Cosmos DB では、この SDK の追加のメンテナンスとサポートが提供されなくなります。 上記の手順に従って Azure Cosmos DB Java SDK v4 に移行することをお勧めします。
Azure Cosmos DB は、高速で柔軟性に優れた分散データベースです。待機時間とスループットが保証されており、シームレスにスケーリングできます。 Azure Cosmos DB でデータベースをスケーリングするために、アーキテクチャを大きく変更したり、複雑なコードを記述したりする必要はありません。 スケールアップとスケールダウンは、API 呼び出しを 1 回行うだけの簡単なものです。 詳細については、 コンテナーのスループットをプロビジョニングする方法 、または データベースのスループットをプロビジョニングする方法を参照してください。 ただし、Azure Cosmos DB はネットワーク呼び出しを介してアクセスされるため、Azure Cosmos DB Sync Java SDK v2 を使用するときにピーク パフォーマンスを実現するために実行できるクライアント側の最適化があります。
データベースのパフォーマンスを向上させる場合は、以下のオプションを検討してください。
ネットワーク
接続モード: DirectHttps を使用する
クライアントが Azure Cosmos DB に接続する方法は、パフォーマンスに重要な影響を与えます。特に、クライアント側の待機時間が観察される点で重要です。 クライアント ConnectionPolicy の構成には、 ConnectionMode という 1 つの主要な構成設定があります。 使用可能な 2 つの ConnectionMode は次のとおりです。
-
ゲートウェイ モードはすべての SDK プラットフォームでサポートされており、構成済みの既定値です。 ファイアウォールの制限が厳しい企業ネットワーク内でアプリケーションを実行する場合、ゲートウェイは標準の HTTPS ポートと単一のエンドポイントを使用するため、最適な選択肢です。 ただし、パフォーマンスのトレードオフは、データが Azure Cosmos DB に読み取りまたは書き込まれるたびにゲートウェイ モードに追加のネットワーク ホップが含まれることです。 このため、DirectHttps モードでは、ネットワーク ホップが少なくなるため、パフォーマンスが向上します。
Azure Cosmos DB Sync Java SDK v2 は、トランスポート プロトコルとして HTTPS を使用します。 HTTPS では、初期認証とトラフィックの暗号化に TLS が使用されます。 Azure Cosmos DB Sync Java SDK v2 を使用する場合は、HTTPS ポート 443 のみを開く必要があります。
ConnectionMode は、ConnectionPolicy パラメーターを使用して DocumentClient インスタンスの構築中に構成されます。
Sync Java SDK V2 (Maven com.microsoft.azure::azure-documentdb)
public ConnectionPolicy getConnectionPolicy() { ConnectionPolicy policy = new ConnectionPolicy(); policy.setConnectionMode(ConnectionMode.DirectHttps); policy.setMaxPoolSize(1000); return policy; } ConnectionPolicy connectionPolicy = new ConnectionPolicy(); DocumentClient client = new DocumentClient(HOST, MASTER_KEY, connectionPolicy, null);
パフォーマンスを確保するために同じ Azure リージョン内にクライアントを併置する
可能であれば、Azure Cosmos DB を呼び出すアプリケーションを Azure Cosmos DB データベースと同じリージョンに配置します。 おおよその比較では、Azure Cosmos DB の呼び出しは、同じリージョン内であれば 1 から 2 ミリ秒以内で完了するのに対し、米国西部と米国東部の間では待ち時間が 50 ミリ秒より長くなります。 要求がクライアントから Azure データセンターの境界まで流れるときに使用されるルートに応じて、この待機時間が要求ごとに異なる可能性があります。 最短の待機時間は、プロビジョニングされた Azure Cosmos DB エンドポイントと同じ Azure リージョン内に呼び出し元アプリケーションを配置することによって実現されます。 使用可能なリージョンの一覧については、「 Azure のリージョン」を参照してください。
SDK の使用状況
最新の SDK をインストールする
Azure Cosmos DB SDK は、最適なパフォーマンスを提供するために頻繁に改善されています。 最新の SDK の改善点を確認するには、Azure Cosmos DB SDK を参照してください。
アプリケーションの有効期間中はシングルトン Azure Cosmos DB クライアントを使用する
各 DocumentClient インスタンスはスレッド セーフであり、ダイレクト モードで動作するときに効率的な接続管理とアドレス キャッシュを実行します。 DocumentClient による効率的な接続管理とパフォーマンスの向上を実現するには、アプリケーションの有効期間中、AppDomain ごとに DocumentClient の単一インスタンスを使用することをお勧めします。
ゲートウェイ モードを使用する場合は、ホストあたりの MaxPoolSize を増やす
Azure Cosmos DB 要求は、ゲートウェイ モードを使用する場合は HTTPS/REST 経由で行われ、ホスト名または IP アドレスごとの既定の接続制限が適用されます。 クライアント ライブラリが Azure Cosmos DB への複数の同時接続を利用できるように、MaxPoolSize を高い値 (200 から 1000) に設定する必要がある場合があります。 Azure Cosmos DB Sync Java SDK v2 では、 ConnectionPolicy.getMaxPoolSize の既定値は 100 です。 setMaxPoolSize を使用して値を変更します。
パーティション分割コレクションの並列クエリのチューニング
Azure Cosmos DB Sync Java SDK バージョン 1.9.0 以降では、並列クエリがサポートされており、パーティション分割されたコレクションに対して並列クエリを実行できます。 詳細については、SDK の操作に関連する コード サンプル を参照してください。 並列クエリは、対応するシリアルクエリよりもクエリの待機時間とスループットを向上するように設計されています。
(a) setMaxDegreeOfParallelism のチューニング: 並列クエリは、複数のパーティションに対して並列クエリを実行することで機能します。 個別のパーティション分割コレクションのデータは、クエリに従って順次フェッチされます。 そのため、 setMaxDegreeOfParallelism を使用して、他のすべてのシステム条件が同じままである場合に、最もパフォーマンスの高いクエリを達成する可能性が最大のパーティション数を設定します。 パーティションの数がわからない場合は、setMaxDegreeOfParallelism を使用して高い数値を設定できます。システムは並列処理の最大限度として最小 (パーティション数、ユーザー指定入力) を選択します。
クエリに関してデータがすべてのパーティションに均等に分散されている場合は、並列クエリが最適な利点を生み出すことに注意してください。 パーティション分割されたコレクションが、クエリによって返されるデータのすべてまたは大部分が少数のパーティション (最悪の場合は 1 つのパーティション) に集中するような方法でパーティション分割されている場合、それらのパーティションによってクエリのパフォーマンスがボトルネックになります。
(b) setMaxBufferedItemCount のチューニング: 並列クエリは、結果の現在のバッチがクライアントによって処理されている間に結果をプリフェッチするように設計されています。 プリフェッチは、クエリの全体的な待機時間の向上に役立ちます。 setMaxBufferedItemCount はプリフェッチされた結果の数を制限します。 setMaxBufferedItemCount を返される予想される結果の数 (またはそれ以上) に設定すると、クエリはプリフェッチによる最大のメリットを受けることができます。
プリフェッチは、MaxDegreeOfParallelism に関係なく同じように機能し、すべてのパーティションのデータに対して 1 つのバッファーがあります。
getRetryAfterInMilliseconds 間隔でバックオフを実装する
パフォーマンス テスト中は、要求のレートが小さくなるまで負荷を増やす必要があります。 制限された場合、クライアントアプリケーションは、サーバーが指定した再試行間隔を設けてスロットルを弱める必要があります。 バックオフを尊重することで、再試行の間に待機する時間を最小限に抑えることができます。 再試行ポリシーのサポートは、 Azure Cosmos DB Sync Java SDK のバージョン 1.8.0 以降に含まれています。 詳細については、「 getRetryAfterInMilliseconds」を参照してください。
クライアント ワークロードをスケールアウトする
高スループット レベル (>50,000 RU/秒) でテストする場合、CPU またはネットワーク使用率でマシンが上限に達したため、クライアント アプリケーションがボトルネックになる可能性があります。 この状態に達しても、クライアント アプリケーションを複数のサーバーにスケールアウトすることで引き続き同じ Azure Cosmos DB アカウントで対応できます。
名前ベースのアドレス指定を使用する
名前ベースのアドレス指定を使用します。リンクの形式は SelfLinks (_self) ではなく、
dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentIdで、リンクの構築に使用されるすべてのリソースの ResourceId を取得しないようにdbs/<database_rid>/colls/<collection_rid>/docs/<document_rid>形式になります。 また、これらのリソースが再作成されるため (同じ名前の場合もあります)、キャッシュに役立たない可能性があります。パフォーマンスを向上させるために、クエリ/読み取りフィードのページ サイズを調整する
読み取りフィード機能 ( readDocuments など) を使用してドキュメントの一括読み取りを実行する場合、または SQL クエリを発行するときに、結果セットが大きすぎる場合は、セグメント化された方法で結果が返されます。 既定では、結果が 100 項目または 1 MB に達した時点で単位として返されます。どちらの上限が最初に達するかによります。
該当するすべての結果を取得するために必要なネットワーク ラウンド トリップの数を減らすために、 x-ms-max-item-count 要求ヘッダーを使用してページ サイズを最大 1000 に増やすことができます。 一部の結果のみを表示する必要がある場合 (たとえば、ユーザー インターフェイスまたはアプリケーション API が一度に 10 件の結果のみを返す場合)、ページ サイズを 10 に減らして、読み取りとクエリに使用されるスループットを減らすこともできます。
setPageSize メソッドを使用してページ サイズを設定することもできます。
インデックス作成ポリシー
インデックス作成から未使用のパスを除外して書き込みを高速化する
Azure Cosmos DB のインデックス作成ポリシーでは、インデックス作成パス (setIncludedPaths と setExcludedPaths ) を使用して、インデックス作成に含める、またはインデックス作成から除外するドキュメント パスを指定 できます。 インデックス作成コストはインデックス付きの一意のパスの数に直接関係するため、パスのインデックス作成を使用すると、クエリ パターンが事前にわかっているシナリオで書き込みパフォーマンスが向上し、インデックス ストレージを削減できます。 たとえば、次のコードは、"*" ワイルドカードを使用してドキュメントのセクション全体 (サブツリー) をインデックス作成から除外する方法を示しています。
Sync Java SDK V2 (Maven com.microsoft.azure::azure-documentdb)
Index numberIndex = Index.Range(DataType.Number); numberIndex.set("precision", -1); indexes.add(numberIndex); includedPath.setIndexes(indexes); includedPaths.add(includedPath); indexingPolicy.setIncludedPaths(includedPaths); collectionDefinition.setIndexingPolicy(indexingPolicy);詳細については、Azure Cosmos DB インデックス作成ポリシーに関するページをご覧ください。
スループット
測定と調整によって 1 秒あたりの要求ユニットの使用量を削減する
Azure Cosmos DB には、UDF、ストアド プロシージャ、トリガーを使ったリレーショナル クエリや階層クエリなど、さまざまなデータベース操作が用意されています。これらの操作はすべて、データベース コレクション内のドキュメントに対して実行できます。 これらの操作のそれぞれに関連付けられたコストは、操作を完了するために必要な CPU、IO、およびメモリに応じて異なります。 ハードウェア リソースの管理について考える代わりに、各種のデータベース操作を実行しアプリケーション要求を処理するのに必要なリソースに関する単一の測定単位として要求単位 (RU) を考えることができます。
コンテナーごとに設定された要求ユニットの数に基づいて、スループットをプロビジョニングします。 要求単位の消費は、1 秒あたりのレートとして評価されます。 コンテナーのプロビジョニング済み要求ユニット レートを超過したアプリケーションは、レートがそのコンテナーにプロビジョニングされているレベルを下回るまで制限されます。 アプリケーションでより高いスループットが必要になった場合は、追加の要求ユニットをプロビジョニングしてスループットを増やすことができます。
クエリの複雑さは、操作で消費される要求ユニット数に影響します。 述語の数、述語の特性、UDF 数、ソース データ セットのサイズのすべてがクエリ操作のコストに影響します。
操作 (作成、更新、または削除) のオーバーヘッドを測定するには、 x-ms-request-charge ヘッダー (または ResourceResponse<T> または FeedResponse<T> の同等の RequestCharge プロパティを調べて、これらの操作で使用される要求ユニットの数を測定します。
Sync Java SDK V2 (Maven com.microsoft.azure::azure-documentdb)
ResourceResponse<Document> response = client.createDocument(collectionLink, documentDefinition, null, false); response.getRequestCharge();このヘッダーで返される要求の使用量は、プロビジョニングしたスループットの一部です。 たとえば、2000 RU/秒がプロビジョニングされていて、上記のクエリで 1,000 1 KB ドキュメントが返された場合、操作のコストは 1000 になります。 そのため、後続の要求をレート制限する前に、サーバーは 1 秒以内にこのような要求を 2 つだけ受け付けます。 詳細については、要求ユニットに関する記事および要求ユニット計算ツールのページを参照してください。
レート制限と大きすぎる要求レートに対処する
クライアントがアカウントの予約済みスループットを超えようとしても、サーバーでパフォーマンスの低下が発生することはなく、予約済みのレベルを超えてスループット容量が使用されることもありません。 サーバーはいち早く RequestRateTooLarge (HTTP 状態コード 429) で要求を終了させ、要求を再試行するまでにユーザーが待機しなければならない時間 (ミリ秒) を示す x-ms-retry-after-ms ヘッダーを返します。
HTTP Status 429, Status Line: RequestRateTooLarge x-ms-retry-after-ms :100SDK はすべてこの応答を暗黙的にキャッチし、サーバーが指定した retry-after ヘッダーを優先して要求を再試行します。 アカウントに複数のクライアントが同時アクセスしている状況でなければ、次回の再試行は成功します。
複数のクライアントが累積的に要求レートを超えて一貫して動作している場合、クライアントによって内部的に現在 9 に設定されている既定の再試行回数では十分ではない可能性があります。この場合、クライアントは状態コード 429 の DocumentClientException をアプリケーションにスローします。 既定の再試行回数は、ConnectionPolicy インスタンスで setRetryOptions を使用して変更できます。 既定では、要求が要求レートを超えて動作し続ける場合、状態コード 429 の DocumentClientException は、累積待機時間が 30 秒後に返されます。 これは、現在の再試行回数が最大再試行回数 (既定値の 9 またはユーザー定義の値) より少ない場合でも発生します。
自動再試行動作により、ほとんどのアプリケーションの回復性とユーザービリティが向上しますが、パフォーマンス ベンチマークの実行時 (特に待機時間の測定時) に問題が生じることがあります。 実験でサーバーが負荷制限に達してクライアント SDK が通知なしに再試行すると、クライアントが観測する待機時間が急増します。 パフォーマンスの実験中に待機時間が急増するのを回避するには、各操作で返される使用量を測定し、予約済みの要求レートを下回った状態で要求が行われていることを確認します。 詳細については、 要求ユニットに関する記事を参照してください。
スループットを向上させるためにサイズの小さいドキュメントに合わせて設計する
特定の操作の要求の使用量 (要求処理コスト) は、ドキュメントのサイズに直接関係します。 サイズの大きいドキュメントの操作は、サイズの小さいドキュメントの操作よりもコストがかかります。
次のステップ
スケーリングと高パフォーマンスのためのアプリケーションの設計について詳しくは、「Azure Cosmos DB でのパーティション分割とスケーリング」をご覧ください。