Azure Cosmos DB .NET SDK の要求タイムアウト例外を診断してトラブルシューティングする

適用対象: NoSQL

HTTP 408 エラーは、タイムアウト制限が発生する前に SDK が要求を完了できなかった場合に発生します。

さまざまなネットワーク状態に正しく反応できるようにするために、アプリケーションの設計は、Microsoft の Azure Cosmos DB SDK を使用して回復性の高いアプリケーションを設計するためのガイドに従っていることが重要です。 分散システムではタイムアウト エラーは通常予期されているので、その場合、アプリケーションでは再試行を行う必要があります。

タイムアウト エラーを評価する場合:

  • 成功した操作の量と影響を受けた操作の量の比較によって、どのような影響が測定されていますか。 サービスの SLA 内にありますか。
  • P99 待機時間および可用性は影響を受けていますか。
  • これらのエラーは、すべてのアプリケーション インスタンスに影響していますか、またはサブセットのみに影響していますか。 問題がインスタンスのサブセットに限定される場合は、通常、これらのインスタンスに関連する問題になります。

Azure Cosmos DB .NET SDK でタイムアウトをカスタマイズする

この SDK には、タイムアウトを制御する方法が 2 つあります。いずれもスコープが異なります。

要求レベルのタイムアウト

CosmosClientOptions.RequestTimeout (SDK v2 の場合は、ConnectionPolicy.RequestTimeout) 構成を使用すると、要求が SDK からネットワーク上に送信された後、応答が受信されるまでの、ネットワーク要求のタイムアウトを設定できます。

CosmosClientOptions.OpenTcpConnectionTimeout (SDK v2 の場合は、ConnectionPolicy.OpenTcpConnectionTimeout) 構成を使用すると、初期接続を開くのに費やされる時間のタイムアウトを設定できます。 接続が開かれると、後続の要求でその接続が使用されます。

ユーザーによって開始された操作は、複数のネットワーク要求にまたがる場合があります (再試行など)。 これら 2 つの構成は要求単位であり、操作のエンド ツー エンド単位ではありません。

CancellationToken

SDK のすべての非同期操作にオプションの CancellationToken パラメーターがあります。 この CancellationToken パラメーターは、すべてのネットワーク要求と再試行にわたって、操作全体を通して使用されます。 ネットワーク要求の合間にキャンセル トークンが確認され、関連トークンの有効期間が切れている場合、操作が取り消されます。 キャンセル トークンは、操作スコープに予想されるおよそのタイムアウトを定義する目的で使用してください。

Note

CancellationToken パラメーターは、取り消しによって無効な状態が引き起こされないときに、ライブラリによって取り消しが確認されるメカニズムです。 取り消しに定義された時間が経過しても、厳密にその時点で操作がキャンセルされない場合があります。 その代わりに、その時間が経過した後、そうしても安全なときにキャンセルされます。

トラブルシューティングの手順

次の一覧には、要求タイムアウト例外の既知の原因と解決方法が含まれています。

CosmosOperationCanceledException

この種の例外は、アプリケーションが CancellationTokens を SDK 操作に渡す際によく発生します。 SDK では、再試行の間に CancellationToken の状態がチェックされます。CancellationToken が取り消された場合、この例外によって現在の操作が中止されます。

例外の Message / ToString() では、Cancellation Token has expired: true を通じて CancellationToken の状態も示され、関連する要求のキャンセルのコンテキストを含む診断も含まれます。

これらの例外は再試行しても問題なく、再試行の観点からタイムアウトとして扱うことができます。

解決策

CancellationToken の構成された時間を確認し、RequestTimeoutCosmosClientOptions.OpenTcpConnectionTimeout (ダイレクト モードを使用している場合) より長いことを確認します。 CancellationToken の使用可能な時間が構成されたタイムアウトより短く、SDK が一時的な接続の問題に直面している場合、SDK は再試行できず、CosmosOperationCanceledException をスローします。

高い CPU 使用率

高い CPU 使用率は最も一般的なケースです。 最適な待機時間を実現するには、CPU 使用率は 40% ほどである必要があります。 CPU 使用率の (平均ではなく) 最大値を監視するには、間隔として 10 秒を使用します。 CPU スパイクは、1 つのクエリに対して複数の接続を実行する可能性があるクロスパーティション クエリでは、より一般的です。

タイムアウトには "診断" が含まれ、それには以下の情報が含まれます。

"systemHistory": [
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
...
]
  • cpu の値が 70% を超える場合、タイムアウトは CPU の枯渇が原因である可能性があります。 この場合の解決策は、CPU 使用率が高いソースを調査してそれを減らすか、マシンをより大きなリソース サイズにスケーリングすることです。
  • threadInfo/isThreadStarving ノードの値が True になっている場合、原因は使用できるスレッドがないことです。 この場合の解決策は、スレッドの枯渇 (ロックされている可能性のあるスレッド) のソースを調査するか、マシンをより大きなリソース サイズにスケーリングすることです。
  • 測定間の dateUtc 時間が約 10 秒でない場合、スレッド プールでの競合も示しています。 CPU は、スレッド プールに 10 秒ごとにエンキューされる独立したタスクとして測定されます。測定間の時間がこれより長い場合、非同期タスクを適切なタイミングで処理できないことを示します。 最も一般的なシナリオは、アプリケーション コードで非同期コードに対する呼び出しをブロックしている場合です。

解決策

SDK を使用するクライアント アプリケーションをスケールアップまたはスケールアウトする必要があります。

ソケットまたはポートの可用性が低下している可能性がある

Azure で実行されている場合、.NET SDK を使用しているクライアントで Azure SNAT (PAT) ポートの枯渇が発生する可能性があります。

解決策 1

Azure VM で実行している場合は、SNAT ポートの枯渇に関するガイドを参照してください。

解決策 2

Azure App Service で実行している場合は、接続エラーのトラブルシューティングのガイドに従って、App Service の診断を利用してください。

解決策 3

Azure Functions で実行している場合は、必要なすべてのサービス (Azure Cosmos DB を含む) に対してシングルトンまたは静的クライアントを管理するための Azure Functions の推奨事項に従っていることを確認します。 関数アプリのホスティングの種類とサイズに基づくサービスの制限を確認します。

解決策 4

HTTP プロキシを使用する場合は、SDK ConnectionPolicy で構成されている接続の数をサポートできることを確認します。 そうしないと、接続の問題が発生します。

複数のクライアント インスタンスの作成

複数のクライアント インスタンスを作成すると、接続の競合とタイムアウトの問題を招くおそれがあります。 診断 には、次の 2 つの関連するプロパティが含まれています:

{
    "NumberOfClientsCreated":X,
    "NumberOfActiveClients":Y,
}

NumberOfClientsCreated は、同じ AppDomain 内で CosmosClient が作成された回数を追跡し、NumberOfActiveClients は、アクティブなクライアント (破棄されていない) を追跡します。 シングルトン パターンに従う場合、X はアプリケーションが使用するアカウントの数と一致し、XYと等しくなります。

XYより大きい場合は、アプリケーションがクライアント インスタンスを作成して破棄することを意味します。 これにより、接続の競合したり、CPU 競合したりする可能性があります。

ソリューション

パフォーマンスに関するヒントに従って、プロセス全体でアカウントごとに単一の CosmosClient インスタンスを使用します。 クライアントの作成と破棄は避けてください。

ホット パーティション キー

Azure Cosmos DB は、プロビジョニングされたスループット全体を物理パーティション間で均等に分散します。 ホット パーティションが存在すると、ある物理パーティション上の 1 つ以上の論理パーティション キーによってその物理パーティションのすべての要求ユニット/秒 (RU/秒) が消費されます。 同時に、他の物理パーティション上の RU/秒は未使用のままになります。 症状としては、消費済み RU/秒の合計は、データベースまたはコンテナー上にプロビジョニングされている全体的な RU/秒よりも少なくなりますが、ホット論理パーティション キーに対する要求では、帯域幅調整 (429) が見られます。 正規化された RU 消費量メトリック を使用して、ワークロードでホット パーティションが発生しているかどうかを確認します。

解決策

要求のボリュームと記憶域を均等に分散する適切なパーティション キーを選択します。 パーティション キーの変更方法を参照してください。

同時実行の程度が高い

アプリケーションで高レベルの同時実行が行われています。これにより、チャネル上で競合が発生する可能性があります。

解決策

SDK を使用するクライアント アプリケーションをスケールアップまたはスケールアウトする必要があります。

大量の要求または応答

要求数や応答数が増大すると、同時実行の程度が比較的低い場合でも、チャネル上でヘッドオブライン ブロッキングが発生し、競合が悪化する可能性があります。

解決策

SDK を使用するクライアント アプリケーションをスケールアップまたはスケールアウトする必要があります。

エラー率が Azure Cosmos DB の SLA に収まっている

アプリケーションでは、一時的なエラーの処理と必要に応じた再試行を実行できる必要があります。 パスの作成時にサービスによって項目が作成されたか否かを知ることはできないため、408 例外は再試行されません。 作成のために同じ項目を再度送信すると、競合例外が発生します。 ユーザー アプリケーションのビジネス ロジックに、競合を処理するためのカスタム ロジックが含まれている場合があります。これにより、既存の項目のあいまいさが解消されたり、作成の再試行と競合したりすることがあります。

エラー率が Azure Cosmos DB の SLA に違反している

Azure サポートにお問い合わせください。

次のステップ