2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Cosmos DBに対する .NET での再試行ロジック

Last updated at Posted at 2022-06-24

はじめに

Cosmos DB の再試行ロジックについてMicrosoft Docsの情報と.NET SDKのソースから自分が理解した内容を残します。
また、本内容に誤りなどありましたら、コメントいただければ幸いです。
なお、2022年6月時点の情報となりますので、今後、仕様が変わる可能性があります。

SDK の接続モード

Cosmos DBの.NET SDKには2つの接続モードが用意されており、いずれの接続モードもSDKにて再試行ロジックが組み込まれています。
接続モード
※イメージの引用元「 Azure Cosmos DB SQL SDK connectivity modes - Available connectivity modes

ゲートウェイ モード(Gateway mode)

  • すべての SDK プラットフォームでサポート
  • プロトコル:HTTPS
  • 単一の DNS エンドポイント
  • ファイアウォールの厳しい制限がある企業ネットワーク内でアプリケーションを実行する場合に最適
  • パフォーマンスはダイレクト モードより不利
    • ネットワーク ホップ:HttpClient → (HTTPS)→ Gateway Service → (TCP) → Replica

ダイレクト モード(Direct mode)

  • .NET と Java SDK プラットフォームでのみサポート
  • プロトコル:TCP(初期認証とトラフィックの暗号化に TLS を使用)
  • アプリケーションからレプリカに直接接続
  • パフォーマンスはゲートウェイ モードより有利
    • ネットワーク ホップ:Transport Client → (TCP) → Replica

SDK にて再試行するエラー時のステータス コード

何れの接続モードでも SDK を利用することで、特定のエラー条件で自動的に再試行されます。

ステータス コード 再試行の追加が必要か SDK で再試行するか 説明
400 いいえ いいえ 正しくない要求
401 いいえ いいえ 許可されていません
403 省略可能 いいえ Forbidden
404 いいえ いいえ リソースが見つかりません
408 はい はい 要求がタイムアウトしました
409 いいえ いいえ 競合エラーは、書き込み操作でリソースに指定された ID (ID とパーティション キー) が既存のリソースによって取得された場合、または一意キー制約に違反した場合に発生します。
410 はい はい Gone 例外 (SLA に違反しない一時的な障害)
412 いいえ いいえ サーバーで利用できるバージョンとは異なる eTag が操作によって指定される場合、前提条件エラーが発生します。
これは、オプティミスティック同時実行制御エラーです。 リソースの最新バージョンを読み取り、要求の eTag を更新した後、要求を再試行してください。
413 いいえ いいえ 要求のエンティティが大きすぎます
429 はい はい 429 の場合は再試行しても問題ありません。
HTTP 429 のトラブルシューティングを行うためのガイドをご確認ください。
449 はい はい 書き込み操作でのみ発生する一時的なエラーであり、再試行しても問題ありません。
これは、Cosmos DB の同じオブジェクトを更新しようとしている同時操作が多すぎるという、設計上の問題を示している可能性があります。
500 いいえ いいえ 予期しないサービス エラーのため、操作に失敗しました。 Azure サポートの問題を提出して、サポートにお問い合わせください。
503 はい はい サービスを利用できません

※表の引用元:Microsoft Docs「Azure Cosmos DB SDK を使用した回復性があるアプリケーションの設計

要求率が大きすぎるエラー(ステータス コード 429)

ステータス コード「429」は「要求率(RU/秒)が大きすぎる」エラー時のコードとなります。
これは Cosmos DB に対する要求がレート制限されていることを示します。

Cosmos DB では、読み取り、書き込み、クエリなどのサービスに対するデータベース操作に、一定量の要求ユニット (RU) が消費されます。
※要求ユニットについては「Azure Cosmos DB の要求ユニット」参照。

そして、Cosmos DB アカウントの種類が「プロビジョニング スループット モード」の場合、スループットを要求率(RU/秒)で設定するため、設定した要求率を超える場合に本エラーが発生します。

大量データの一括登録などで容易に発生するため、本エラーに対する再試行ロジックについて後述します。

要求率が大きすぎるエラーに対する SDK での再試行ロジック

前提知識

  • 最大再試行回数は、CosmosClientOptionsMaxRetryAttemptsOnRateLimitedRequestsプロパティで保持します。
    • デフォルト値は9回であり、エラーがアプリケーションに返される前に、同じ要求がサーバーに最大10回発行されることを意味します。
  • 最大再試行待機時間は、CosmosClientOptionsMaxRetryWaitTimeOnRateLimitedRequestsプロパティで保持します。
    • デフォルト値は30秒です。
    • 最小間隔は秒で、これよりも小さい間隔は無視されます。
    • 累積待機時間がこの値を超えると、クライアントは再試行を停止し、エラーをアプリケーションに返します。

再試行ロジック

アプリケーションが Cosmos DB SDK を利用して、Cosmos DB に要求を発行した際に「要求率が大きすぎる(429)」エラーが発生した場合の動作概要です。

  1. Cosmos DB から「要求率が大きすぎる(429)」の応答を返す。
  2. Cosmos DB SDK が、応答内の x-ms-retry-after-ms ヘッダーにある待機時間分、待機後、再試行する。
    a. 待機時間の累積がCosmosClientOptionsの最大再試行待機時間を超える場合、アプリケーションに「要求率が大きすぎる(429)」エラーを返します。
    b. 再試行回数がCosmosClientOptionsの最大再試行回数を超える場合、アプリケーションに「要求率が大きすぎる(429)」エラーを返します。
  3. Cosmos DB から成功の応答を返す。
  4. Cosmos DB SDK が、アプリケーションに成功の応答を返す。

アプリケーションが「要求率が大きすぎる(429)」エラーを受け取る場合、Cosmos DB SDK の再試行ロジックでは対処しきれなかった結果のため、以下の対応を検討します。

  • CosmosClientOptionsの最大再試行回数と最大再試行待機時間を増やすなど調整する。
    • ソースのイメージ
      // CosmosClientオブジェクトを初期化
      CosmosClient cosmosClient = new CosmosClient(EndpointUrl, AuthorizationKey,
           new CosmosClientOptions() {
                   /* オプション設定・・・ */, 
                   MaxRetryAttemptsOnRateLimitedRequests = 19, // 最大再試行回数を増やす(9回 → 19回)
                   MaxRetryWaitTimeOnRateLimitedRequests = new TimeSpan(0, 2, 0) // 最大再試行待機時間を増やす(30秒 → 2分)
           });
      
  • 指数バックオフ アルゴリズム、または「要求率が大きすぎる(429)」エラーでの再試行を拡張するよう、クライアントを構成する。

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?