Azure Cosmos DB SDK を使用した回復性があるアプリケーションの設計
適用対象: NoSQL
SDK を介して Azure Cosmos DB と対話するクライアント アプリケーションを作成する場合は、いくつかの主要な基本事項を理解することが重要です。 この記事は、これらの基本事項を理解し、回復性があるアプリケーションを設計するのに役立つ設計ガイドです。
概要
この記事で説明する概念のビデオの概要については、以下を参照してください。
接続モード
Azure Cosmos DB SDK は、2 つの接続モードでサービスに接続できます。 .NET SDK と Java SDK は、ゲートウェイ モードとダイレクト モードの両方でサービスに接続できます。他の SDK はゲートウェイ モードでのみ接続できます。 ゲートウェイ モードでは HTTP プロトコルが使用され、ダイレクト モードでは通常 TCP プロトコルが使用されます。
ゲートウェイ モードは、SDK で使用するように構成されているモードに関係なく、アカウント、コンテナー、ルーティング情報などのメタデータをフェッチするために、常に使用されます。 この情報はメモリにキャッシュされ、サービス レプリカへの接続に使用されます。
要約すると、ゲートウェイ モードの SDK の場合は HTTP トラフィックを想定できます。一方、ダイレクト モードの SDK の場合は、さまざまな状況 (初期化、メタデータのフェッチ、ルーティング情報など) で HTTP トラフィックと TCP トラフィックの組み合わせを想定できます。
クライアント インスタンスと接続
接続モードに関係なく、アプリケーションごとにアカウント別で SDK クライアントのシングルトン インスタンスを維持する必要があります。 HTTP と TCP のどちらの接続でも、クライアント インスタンスにスコープが設定されます。 ほとんどのコンピューティング環境には、同時に開くことができる接続の数に関する制限があり、これらの制限に達すると接続が影響を受けます。
分散型アプリケーションとネットワーク
分散型アプリケーションを設計する場合、次の 3 つの主要なコンポーネントがあります。
- アプリケーションとそれが実行されている環境。
- ネットワーク。このネットワークには、アプリケーションと Azure Cosmos DB サービス エンドポイントの間のコンポーネントが含まれます。
- Azure Cosmos DB サービス エンドポイント。
障害が発生する場合、多くの場合はこれら 3 つの領域の 1 つに分類されます。システムの分散型の性質により、これらのコンポーネントの 100 % の可用性を想定することが現実的ではない点を理解することが重要です。
Azure Cosmos DB には包括的な可用性 SLA のセットがありますが、いずれも 100 % ではありません。 アプリケーションをサービス エンドポイントに接続するネットワーク コンポーネントでは、一時的なハードウェアの問題が発生し、パケットが失われる可能性があります。 アプリケーションが実行されているコンピューティング環境でも、操作に影響を与える CPU スパイクが発生する可能性があります。 これらのエラー状態は SDK の操作に影響を与え、通常は特定のコードのエラーとして表示されます。
SDK によって提供される応答に対して再試行ポリシーを実装すれば、アプリケーションは、これらのコンポーネント全体でのある程度の潜在的な障害に対する回復性を備えることができます。
エラー時にアプリケーションを再試行する必要はありますか。
短く答えれば、はいになります。 ただし、すべてのエラーに対して再試行が有効であるわけではなく、一部のエラー コードまたは状態コードは一時的なものではありません。 下の表では、これらの詳細について説明します。
状態コード | 再試行の追加が必要か | SDK の再試行 | 説明 |
---|---|---|---|
400 | いいえ | いいえ | 正しくない要求 |
401 | いいえ | いいえ | 許可されていません |
403 | 省略可能 | いいえ | Forbidden |
404 | いいえ | いいえ | リソースが見つかりません |
408 | はい | はい | 要求がタイムアウトしました |
409 | いいえ | いいえ | 競合エラーは、書き込み操作でリソースに指定された ID (ID とパーティション キー) が既存のリソースによって取得された場合、または一意キー制約に違反した場合に発生します。 |
410 | はい | はい | Gone 例外 (SLA に違反しない一時的な障害) |
412 | いいえ | いいえ | サーバーで利用できるバージョンとは異なる eTag が操作によって指定される場合、前提条件エラーが発生します。 これは、オプティミスティック同時実行制御エラーです。 リソースの最新バージョンを読み取り、要求の eTag を更新した後、要求を再試行してください。 |
413 | いいえ | いいえ | 要求のエンティティが大きすぎます |
429 | はい | はい | 429 の場合は再試行しても問題ありません。 HTTP 429 のトラブルシューティングを行うためのガイドをご確認ください。 |
449 | はい | はい | 書き込み操作でのみ発生する一時的なエラーであり、再試行しても問題ありません。 これは、Azure Cosmos DB の同じオブジェクトを更新しようとしている同時操作が多すぎるという、設計上の問題を示している可能性があります。 |
500 | いいえ | いいえ | 予期しないサービス エラーのため、操作に失敗しました。 Azure サポートの問題を提出して、サポートにお問い合わせください。 |
503 | はい | はい | サービスを利用できません |
上の表では、2 列目にはいとマークされている状態コードはすべて、アプリケーションである程度の再試行に対応しています。
HTTP 403
Azure Cosmos DB SDK は、通常は HTTP 403 エラーの発生時に再試行しませんが、HTTP 403 に関連する特定のエラーに対しては、アプリケーションで対応することができます。 たとえば、パーティション キーがいっぱいであることを示すエラーが表示された場合は、ビジネス ルールに基づいて書き込もうとしているドキュメントのパーティション キーを変更することができます。
HTTP 429
Azure Cosmos DB SDK は、指定された時間待機してから再試行することで、既定でクライアント構成に従い、サービスの応答 x-ms-retry-after-ms
ヘッダーを受け入れて、HTTP 429 エラーの発生時に再試行します。
SDK の再試行回数を超えると、アプリケーションにエラーが返されます。 応答内の x-ms-retry-after-ms
ヘッダーを調査し、要求を再試行する前に待機する時間を決定するヒントとして使用するのが理想的です。 もう 1 つの方法は、指数バックオフ アルゴリズム、または HTTP 429 に対する再試行を拡張するためにクライアントを構成することです。
HTTP 449
Azure Cosmos DB SDK は、ほとんどのシナリオに対応するために、一定の期間に増分バックオフを使用して HTTP 449 の発生時に再試行します。
SDK の自動再試行回数を超えると、アプリケーションにエラーが返されます。 HTTP 449 エラーは安全に再試行できます。 書き込み操作の同時性が非常に高いので、一定の間隔の後で同程度の同時実行が繰り返されるのを避けるために、ランダムなバックオフ アルゴリズムを使用することをお勧めします。
タイムアウトと接続関連のエラー (HTTP 408/503)
ネットワーク タイムアウトと接続エラーは、最も一般的なエラーの 1 つです。 Azure Cosmos DB SDK はそれ自体に回復性があり、再試行が可能な場合は HTTP プロトコルと TCP プロトコル全体でタイムアウトと接続の問題を再試行します。
- 読み取り操作の場合、SDK はタイムアウトまたは接続関連のエラーを再試行します。
- 書き込み操作の場合、これらの操作はべき等ではないので、SDK は再試行を行いません。 応答の待機中にタイムアウトが発生した場合、要求がサービスに到達したかどうかを知ることはできません。
アカウントに複数のリージョンがある場合、SDK はリージョンをまたがる再試行も実行します。
タイムアウトと接続エラーの性質により、サービス側で発生した障害のみが対象とされるため、アカウントのメトリクスにエラーが表示されない場合があります。
アプリケーションには、これらのシナリオで独自の再試行ポリシーを設定し、書き込みタイムアウトを解決する方法を考慮することをお勧めします。 たとえば、作成タイムアウトで再試行すると、前の要求がサービスに到達していた場合は HTTP 409 (競合) が発生する可能性がありますが、到達していなかった場合は成功します。
言語固有の実装の詳細
言語に関する実装の詳細については、次を参照してください。
再試行は待ち時間に影響しますか。
クライアント パースペクティブにより、すべての再試行は、操作のエンドツーエンドの待ち時間に影響します。 アプリケーションの P99 待機時間が影響を受けている場合は、発生している再試行とその対処方法を理解することが重要です。
Azure Cosmos DB SDK は、実行されている再試行を特定するのに役立つ詳細情報をログと診断で提供します。 詳細については、.NET SDK 診断の収集方法および Java SDK 診断の収集方法に関する記事を参照してください。
再試行の待機時間を軽減するにはどうすればよいですか?
状況に応じて、ほとんどの場合、SDK はローカル リージョン、書き込みリージョン (単一リージョンの書き込みシナリオ)、または 優先リージョンの最初のリージョン一覧に要求をルーティングします。 この優先順位付けにより、最も近いデータ センターまたは最適なデータ センターに主に接続することで、正常なシナリオの待機時間が最小限に抑えられます。
ただし、この優先順位付けは、特定のエラー シナリオでは、失敗につながる要求が常に特定のリージョンで最初に試行されることも意味します。 そのシナリオで別のリージョンへのフェールオーバーが推奨される場合、これは通常、SDK レベルではなくインフラストラクチャ (Traffic Manager) レイヤーで処理されます。 インフラストラクチャの適切なセットアップと構成により、リージョンの停止中にトラフィックが効率的に再ルーティングされ、障害シナリオでリージョン間の再試行に伴う待機時間を軽減できます。 インフラストラクチャ レベルのフェールオーバーの設定の詳細については、「Azure Traffic Manager のドキュメント」を参照してください。 一部の SDK では、SDK レベルで同様のフェールオーバー戦略を直接実装できます。 たとえば、「Java SDK の高可用性」を参照してください。
リージョンの障害について
Azure Cosmos DB SDK は、リージョン別の提供状況を把握し、別のアカウント リージョンで再試行を実行できます。 他のリージョンを使用するシナリオについては、複数リージョン環境での再試行シナリオと構成に関する記事を参照してください。
カスタマー サポートに問い合わせる状況
カスタマー サポートに問い合わせる前に、次の項目を確認してください。
- 成功した操作の量と影響を受けた操作の量の比較によって、どのような影響が測定されていますか。 サービスの SLA 内にありますか。
- P99 待機時間は影響を受けていますか。
- アプリケーションが再試行する必要があるエラー コードに関連するエラーはありますか。また、アプリケーションはこのような再試行に対応していますか。
- これらのエラーは、すべてのアプリケーション インスタンスに影響していますか、またはサブセットのみに影響していますか。 問題がインスタンスのサブセットに限定される場合は、通常、これらのインスタンスに関連する問題になります。
- 上の表にある関連するトラブルシューティング ドキュメントを使用して、アプリケーション環境の問題を除外していますか。
すべてのアプリケーション インスタンスが影響を受ける場合、または影響を受ける操作の割合がサービスの SLA 範囲外である場合、またはアプリケーションの独自の SLA と P99 に影響を与える場合は、カスタマー サポートにお問い合わせください。
次の手順
- 複数リージョン環境での再試行シナリオと構成の詳細を確認します
- 可用性の SLA を確認します
- 最新の .NET SDK を使用する
- 最新の Java SDK を使用する
- 最新の Python SDK を使用する
- 最新の Node SDK を使用する