DynamoDB でのエラー処理 - Amazon DynamoDB

「翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。」

DynamoDB でのエラー処理

このセクションでは、ランタイムエラーとその処理方法について説明します。また、Amazon DynamoDB 特有のエラーメッセージとコードについて説明します。

エラーコンポーネント

プログラムがリクエストを送信すると、DynamoDB は処理を試行します。リクエストが成功した場合、DynamoDB は要求されたオペレーションからの結果とともに、成功の HTTP ステータスコード (200 OK) を返します。

リクエストが正常に行われなかった場合、DynamoDB はエラーを返します。それぞれのエラーには、次の三つのコンポーネントがあります:

  • HTTP ステータスコード (400 など)。

  • 例外の名前 (ResourceNotFoundException など)。

  • エラーメッセージ (Requested resource not found: Table: tablename not found など)。

AWS SDKs によりアプリケーションにエラーが伝達されるため、適切なアクションを実行できます。たとえば、Java プログラムでは、 try-catch を処理する ResourceNotFoundException ロジックを記述できます。

AWS SDK を使用していない場合は、DynamoDB からの低レベルのレスポンスの内容も解析する必要があります。以下に、そのようなレスポンスの例を示します。

HTTP/1.1 400 Bad Request x-amzn-RequestId: LDM6CJP8RMQ1FHKSC1RBVJFPNVV4KQNSO5AEMF66Q9ASUAAJG Content-Type: application/x-amz-json-1.0 Content-Length: 240 Date: Thu, 15 Mar 2012 23:56:23 GMT {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException", "message":"Requested resource not found: Table: tablename not found"}

エラーメッセージおよびコード

DynamoDB によって返される例外のリストを HTTP ステータスコードごとに次に示します。再試行してもいいですかはいであれば、同じリクエストを再度送信できます。再試行してもいいですかいいえであれば、新しいリクエストを送信する前に、クライアント側で問題を修正する必要があります。

HTTP ステータスコード 400

HTTP ステータスコード400は、認証の失敗、必須パラメータの欠落、またはテーブルにプロビジョニングされているスループットの超過などのリクエストに関連した問題があることを示しています。リクエストを再度送信する前に、アプリケーションで問題を修正する必要があります。

AccessDeniedException

メッセージ: アクセスが拒否されました。

クライアントがリクエストに正しく署名しませんでした。AWS SDK を使用している場合、リクエストは自動的に署名されます。それ以外の場合は、https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html にある署名バージョン 4 の署名プロセスAWS General Referenceを参照してください。

再試行してもいいですか。なし

ConditionalCheckFailedException

メッセージ: 条件付きリクエストが失敗しました。

false と評価された条件を指定しました。たとえば、項目に条件付き更新を実行しようとしたかもしれませんが、属性の実際の値は、条件の予期される値と一致しませんでした。

再試行してもいいですか。なし

IncompleteSignatureException

メッセージ: リクエストの署名が AWS 基準に適合しません。

リクエストの署名に、必要なすべての要素が含まれていませんでした。AWS SDK を使用している場合、リクエストは自動的に署名されます。それ以外の場合は、https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html にある署名バージョン 4 の署名プロセスAWS General Referenceを参照してください。

再試行してもいいですか。なし

ItemCollectionSizeLimitExceededException

メッセージ: コレクションサイズが超過しました。

local secondary index があるテーブルの場合、同じパーティションキー値を持つ項目のグループが、10 GB の最大サイズ制限を超過しました。項目コレクションの詳細については、「項目コレクション」を参照してください。

再試行してもいいですか。あり

LimitExceededException

メッセージ: 特定の受信者に対するオペレーションが多すぎます。

同時オペレーションのコントロールプレーンが多すぎます。CREATINGDELETING または UPDATING の状態のテーブルやインデックスの累積数が、50 を超えることはできません。

再試行してもいいですか。あり

MissingAuthenticationTokenException

メッセージ: リクエストには、有効な (登録された) AWS アクセスキー ID が含まれている必要があります。

リクエストに、必要な認証ヘッダーが含まれていないか、または正しい形式ではありません。「DynamoDB 低レベル API」を参照してください。

再試行してもいいですか。なし

ProvisionedThroughputExceededException

メッセージ: テーブルまたは 1 つ以上のグローバルセカンダリインデックスのプロビジョニングされたスループットが許容されている最大値を超えました。プロビジョンドスループットと消費スループットのパフォーマンスメトリクスを表示するには、Amazon CloudWatch コンソールを開きます。

例: リクエストレートが高すぎます。AWS SDKs for DynamoDB は、この例外を受け取ったリクエストを自動的に再試行します。リクエストは最終的に成功しますが、再試行キューが大きすぎて終了しない場合もあります。エラーの再試行とエクスポネンシャルバックオフ を使用して、リクエストの頻度を少なくします。

再試行してもいいですか。あり

RequestLimitExceeded

メッセージ: スループットがアカウントの現在のスループット制限を超えています。制限の増加をリクエストするには、https://aws.amazon.com/support で AWS サポートに連絡してください。

例: オンデマンドリクエストの速度が、許容されているアカウントのスループットを超えています。

再試行してもいいですか。あり

ResourceInUseException

メッセージ: 変更しようとしているリソースは使用中です。

例: 既存のテーブルを再作成しようとしたか、CREATING 状態にあるテーブルを削除しようとしました。

再試行してもいいですか。なし

ResourceNotFoundException

メッセージ: リクエストされたリソースが見つかりません。

例: リクエストされたテーブルが存在しないか、ごく初期の CREATING 状態にあります。

再試行してもいいですか。なし

ThrottlingException

メッセージ: リクエストの速度が、許容されているスループットを超えています。

この例外は、AmazonServiceException レスポンスとして、TROTTLING_EXCEPTION ステータスコードと共に返されます。この例外は、コントロールプレーン API オペレーションの実行が速すぎる場合に返される可能性があります。

オンデマンドモードを使用するテーブルの場合、リクエストレートが高すぎると、データプレーン API オペレーションでこの例外が返されることがあります。オンデマンドスケーリングの詳細については、「ピークトラフィックとスケーリングプロパティ」を参照してください。

再試行してもいいですか。あり

UnrecognizedClientException

メッセージ: アクセスキー ID またはセキュリティトークンが無効です。

リクエスト署名が間違っています。最も可能性の高い原因は、AWS アクセスキー ID またはシークレットキーが無効であることです。

再試行してもいいですか。あり

ValidationException

メッセージ: 発生した特定のエラーによって異なります

このエラーは、必須パラメータが指定されていない、値が範囲外である、データ型が一致しない、などいくつかの理由で発生します。エラーメッセージに、エラーを引き起こしたリクエストの特定部分に関する詳細が含まれています。

再試行してもいいですか。なし

HTTP ステータスコード 5xx

HTTP ステータスコード 5xx は、AWS で解決する必要のある問題を示しています。これは一時的なエラーかもしれず、その場合はリクエストを再試行することで成功する場合があります。それ以外の場合、サービスに運用上の問題があるかどうかを確認するために、AWS サービスヘルスダッシュボードを参照してください。

Internal Server Error (HTTP 500)

DynamoDB でリクエストを処理できませんでした。

再試行してもいいですか。あり

注記

項目の操作中に内部サーバーエラーが発生することがあります。これはテーブルの存続期間中に発生すると予想されます。失敗したリクエストは速やかに再試行できます。

Service Unavailable (HTTP 503)

DynamoDB は現在利用できません。(これは一時的な状態です。)

再試行してもいいですか。あり

アプリケーションのエラー処理

アプリケーションをスムーズに実行するには、エラーを見つけ、エラーに対応するロジックを組み込む必要があります。一般的な方法には、try-catchブロックやif-thenステートメントの使用などがあります。

AWS SDKs は独自に再試行とエラーチェックを実行します。いずれかの AWS SDKs の使用中にエラーが発生した場合は、エラーコードと説明が問題のトラブルシューティングに役立ちます。

また、レスポンスにRequest IDが表示されます。Request IDは、AWS サポートを使用して問題を診断することが必要な場合に便利です。

次の Java サンプルコードは、DynamoDB テーブルから項目の取得を試み、基本的なエラー処理を実行します。(この場合、ユーザーにはリクエストが失敗したとだけ通知されます)。

Table table = dynamoDB.getTable("Movies"); try { Item item = table.getItem("year", 1978, "title", "Superman"); if (item != null) { System.out.println("Result: " + item); } else { //No such item exists in the table System.out.println("Item not found"); } } catch (AmazonServiceException ase) { System.err.println("Could not complete operation"); System.err.println("Error Message: " + ase.getMessage()); System.err.println("HTTP Status: " + ase.getStatusCode()); System.err.println("AWS Error Code: " + ase.getErrorCode()); System.err.println("Error Type: " + ase.getErrorType()); System.err.println("Request ID: " + ase.getRequestId()); } catch (AmazonClientException ace) { System.err.println("Internal error occurred communicating with DynamoDB"); System.out.println("Error Message: " + ace.getMessage()); }

このサンプルコードでは、try-catch の構成は 2 つの異なるタイプの例外を処理します:

  • AmazonServiceException — クライアントリクエストが DynamoDB に正しく送信されたが、DynamoDB がリクエストを処理できず、代わりにエラーレスポンスを返した場合にスローされます。

  • AmazonClientException — クライアントがサービスからレスポンスを取得できなかったか、クライアントがサービスからレスポンスを解析できなかった場合にスローされます。

エラーの再試行とエクスポネンシャルバックオフ

特定のリクエストの処理中には、DNS サーバー、スイッチ、ロードバランサーなど、ネットワーク上のさまざまなコンポーネントが原因でエラーが発生する可能性があります。ネットワーク環境内でこれらのエラー応答を処理する一般的な手法としては、クライアントアプリケーションに再試行を実装する方法が挙げられます。この手法により、アプリケーションの信頼性が向上します。

各 AWS SDK は、自動的に再試行ロジックを実装しています。必要に応じて再試行パラメータを変更できます。たとえば、エラーが発生したら再試行が許可されない、Fail-Fast 方式を要求する Java アプリケーションについて考えてみましょう。AWS SDK for Java では、ClientConfiguration クラスを使用して maxErrorRetry の値を 0 に設定することで、再試行を無効にできます。詳細については、AWS SDK ドキュメントのご使用のプログラミング言語の項目を参照してください。

AWS SDK を使用していない場合は、サーバーエラー (5xx) を受け取る元のリクエストを再試行する必要があります。ただし、クライアントエラー (4xx、ThrottlingException または ProvisionedThroughputExceededException 以外) は、再試行する前にリクエスト自体を修正して問題を解決する必要があることを示しています。

単純な再試行に加えて、各 AWS SDK は効果的なフロー制御を行うために、エクスポネンシャルバックオフアルゴリズムを実装します。エクスポネンシャルバックオフは、再試行間の待機時間を累進的に長くして、連続的なエラー応答を受信するという概念に基づいています。たとえば、1 回目の再試行の前に最大 50 ミリ秒、2 回目の前に最大 100 ミリ秒、3 回目の前に最大 200 ミリ秒のようになります。ただし 1 分を経過してもリクエストが成功しない場合は、問題の原因はリクエストの速度ではなく、プロビジョニングしたスループットをリクエストのサイズが超えたためである可能性があります。1 分程度で再試行が停止するように最大回数を設定します。リクエストが失敗した場合は、プロビジョニングしたスループットオプションを調べてください。

注記

AWS SDKs は自動再試行ロジックとエクスポネンシャルバックオフを実装します。

ほとんどのエクスポネンシャルバックオフアルゴリズムは、衝突の連続を防ぐためにジッター (ランダム化された遅延) を使用します。この場合は、そうした衝突を回避しようとしていないので、乱数を使用する必要はありません。ただし、同時クライアントを使用すると、ジッターはリクエストを迅速に処理する助けになります。詳細については、「Exponential Backoff and Jitter」に関するブログ投稿を参照してください。

バッチオペレーションとエラー処理

低レベル API では、読み取りと書き込みのバッチオペレーションがサポートされています。DynamoDBBatchGetItem は 1 つ以上のテーブルから項目を読み取り、BatchWriteItem は 1 つ以上のテーブルで項目を入力または削除します。これらのバッチオペレーションはバッチ以外の DynamoDB オペレーションのラッパーとして実装されています。つまり、BatchGetItem は、バッチの項目ごとに GetItem を一度呼び出します。同様に、BatchWriteItem は、DeleteItem または PutItem を必要に応じてバッチの項目ごとに呼び出します。

バッチオペレーションではバッチの個々のリクエストのエラーが許容されます。たとえば、5 つの項目を読み込む BatchGetItem リクエストの場合を考えます。基礎となる GetItem リクエストの一部が失敗した場合でも、BatchGetItem オペレーション全体が失敗することはありません。ただし、5 つのオペレーションにすべて失敗する場合は、BatchGetItem 全体が失敗します。

バッチオペレーションでは、失敗した個々のリクエストについて情報が返されるため、問題を診断し、オペレーションを再試行できます。BatchGetItem の場合、問題のあるテーブルとプライマリキーがレスポンスの UnprocessedKeys 値で返されます。BatchWriteItem の場合、同様の情報は UnprocessedItems で返されます。

読み込みまたは書き込みの失敗の原因として最も可能性が高いのは、スロットリングです。BatchGetItem の場合、バッチリクエストの 1 つ以上のテーブルに、オペレーションをサポートするための十分なプロビジョンド読み込みキャパシティーがなくなります。BatchWriteItem の場合、1 つ以上のテーブルに、十分なプロビジョンド書き込みキャパシティーがなくなります。

DynamoDB によって未処理の項目が返された場合は、それらの項目に対してバッチオペレーションを再試行する必要があります。ただし、エクスポネンシャルバックオフアルゴリズムを使用することを強くお勧めします。すぐにバッチオペレーションを再試行した場合、基礎となる読み込みまたは書き込みリクエストはやはり、個々のテーブルに対する帯域幅調整により失敗することがあります。エクスポネンシャルバックオフアルゴリズムを使用してバッチオペレーションを遅らせた場合は、バッチの個々のリクエストが成功する可能性がはるかに高くなります。