

# DynamoDB 관련 오류 처리
<a name="Programming.Errors"></a>

 이 단원에서는 런타임 오류와 그러한 오류를 처리하는 방법을 설명합니다. 또한 Amazon DynamoDB 관련 오류 메시지 및 코드를 설명합니다. 모든 AWS 서비스에 적용되는 일반적인 오류 목록은 [액세스 관리](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html)를 참조하세요.

**Topics**
+ [오류 구성 요소](#Programming.Errors.Components)
+ [트랜잭션 오류](#Programming.Errors.TransactionalErrors)
+ [오류 메시지 및 코드](#Programming.Errors.MessagesAndCodes)
+ [애플리케이션에서의 오류 처리](#Programming.Errors.Handling)
+ [오류 재시도 횟수 및 지수 백오프](#Programming.Errors.RetryAndBackoff)
+ [일괄 작업 및 오류 처리](#Programming.Errors.BatchOperations)

## 오류 구성 요소
<a name="Programming.Errors.Components"></a>

프로그램이 요청을 보내면 DynamoDB는 요청 처리를 시도합니다. 요청이 성공하면 DynamoDB는 요청된 작업의 결과와 함께 HTTP 성공 상태 코드(`200 OK`)를 반환합니다.

요청이 실패하면 DynamoDB는 오류를 반환합니다. 오류에는 세 가지 구성 요소가 있습니다.
+ HTTP 상태 코드(예: `400`).
+ 예외 이름(예: `ResourceNotFoundException`).
+ 오류 메시지(예: `Requested resource not found: Table: tablename not found`).

AWS SDK는 사용자가 적절한 조치를 취할 수 있도록 애플리케이션에 오류를 전파합니다. 예를 들어 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"}
```

## 트랜잭션 오류
<a name="Programming.Errors.TransactionalErrors"></a>

트랜잭션 오류에 대한 자세한 내용은 [DynamoDB의 트랜잭션 충돌 처리](transaction-apis.md#transaction-conflict-handling) 섹션을 참조하세요.

## 오류 메시지 및 코드
<a name="Programming.Errors.MessagesAndCodes"></a>

다음은 DynamoDB가 반환하는 예외 목록을 HTTP 상태 코드를 기준으로 그룹화한 목록입니다. *재시도 가능?*이 *예*라면 동일한 요청을 다시 제출할 수 있습니다. *재시도 가능?*이 *아니요*라면 새로운 요청을 제출하기 전에 클라이언트 측에서 문제를 해결해야 합니다.

### HTTP 상태 코드 400
<a name="Programming.Errors.MessagesAndCodes.http400"></a>

HTTP `400` 상태 코드는 인증 실패, 필수 파라미터 누락, 테이블의 할당 처리량 초과 등 요청에 문제가 있음을 의미합니다. 요청을 다시 제출하기 전에 애플리케이션의 문제를 해결해야 합니다.

**AccessDeniedException **  
메시지: *액세스가 거부되었습니다.*  
클라이언트가 요청에 정확히 서명하지 않았습니다. AWS SDK를 사용 중인 경우 요청에 자동으로 서명됩니다. 그렇지 않은 경우 **AWS 일반 참조의 [서명 버전 4 서명 프로세스](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)로 이동하세요.  
재시도 가능? 아니요

**ConditionalCheckFailedException**  
메시지: *조건부 요청이 실패했습니다. *   
false로 평가된 조건을 지정했습니다. 예를 들어 어떤 항목에서 조건부 업데이트 수행을 시도했지만 속성의 실제 값이 조건에서 예상되는 값과 일치하지 않았을 수 있습니다.  
재시도 가능? 아니요

**IncompleteSignatureException**  
메시지: *요청 서명이 AWS 표준을 준수하지 않습니다.*  
요청 서명에 일부 필요한 구성 요소가 빠져있습니다. AWS SDK를 사용 중인 경우 요청에 자동으로 서명됩니다. 그렇지 않은 경우 **AWS 일반 참조의 [서명 버전 4 서명 프로세스](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)로 이동하세요.  
재시도 가능? 아니요

**ItemCollectionSizeLimitExceededException**  
메시지: *그룹 크기 제한이 초과됐습니다.*  
로컬 보조 인덱스가 포함된 테이블에서 동일한 파티션 키 값의 항목 그룹이 최대 크기 제한 10GB를 초과하였습니다. 항목 그룹에 대한 자세한 내용은 [로컬 보조 인덱스의 항목 컬렉션](LSI.md#LSI.ItemCollections) 단원을 참조하세요.  
재시도 가능? 예

**LimitExceededException**  
메시지: *임의 구독자의 작업이 너무 많습니다.*  
동시 제어 플레인 작업이 너무 많습니다. `CREATING`, `DELETING` 또는 `UPDATING` 상태의 누적 테이블 및 인덱스 수는 500을 초과할 수 없습니다.  
재시도 가능? 예

**MissingAuthenticationTokenException**  
메시지: *요청에는 유효한(등록된) AWS 액세스 키 ID가 포함되어야 합니다.*  
요청이 필요한 인증 헤더를 포함하지 않았거나 잘못된 형식입니다. [DynamoDB 하위 수준 API](Programming.LowLevelAPI.md)을(를) 참조하세요.  
재시도 가능? 아니요

**ProvisionedThroughputExceededException**  
메시지: *테이블 또는 하나 이상의 글로벌 보조 인덱스에게 허용되는 최대 프로비저닝된 처리량을 초과하였습니다. 프로비저닝된 처리량과 소비한 처리량의 성능 지표를 보려면 [Amazon CloudWatch 콘솔](https://console.aws.amazon.com/cloudwatch/home)을 여세요.*  
오류에는 스로틀링이 발생한 구체적인 원인을 설명하는 `ThrottlingReason` 필드 목록이 포함되어 있으며, `ResourceType+OperationType+LimitType` 형식(예: `TableReadProvisionedThroughputExceeded`)과 영향을 받은 리소스의 ARN을 따릅니다. 이를 통해 스로틀링이 적용된 리소스(테이블 또는 인덱스), 스로틀링을 유발한 작업 유형(읽기 또는 쓰기), 초과된 특정 한도(이 경우: 프로비저닝된 용량)를 식별할 수 있습니다. 스로틀링 문제 진단 및 해결에 대한 자세한 내용은 [스로틀링 진단](throttling-diagnosing-workflow.md) 섹션을 참조하세요.  
예: 요청량이 너무 높습니다. DynamoDB용 AWS SDK가 이 예외를 수신하는 요청을 자동으로 재시도합니다. 재시도 대기열이 너무 많아 완료하지 못하는 경우를 제외하고 결국 요청이 성공합니다. [오류 재시도 횟수 및 지수 백오프](#Programming.Errors.RetryAndBackoff)를 사용하여 요청 빈도를 줄입니다.  
재시도 가능? 예

**ReplicatedWriteConflictException**  
메시지: *One or more items in this request are being modified by a request in another Region.*  
예: 현재 다른 리전의 요청에 의해 수정 중인 다중 리전 강력한 일관성(MRSC) 글로벌 테이블의 항목에 대해 쓰기 작업이 요청되었습니다.  
재시도 가능? 예

**RequestLimitExceeded**  
메시지: *처리량이 계정에 대한 현재 처리량 한도를 초과합니다. 한도 증가를 요청하려면 AWS Support([https://aws.amazon.com/support](https://aws.amazon.com/support))에 문의하세요*.  
오류에는 스로틀링이 발생한 구체적인 원인을 설명하는 `ThrottlingReason` 필드 목록이 포함되어 있으며, `ResourceType+OperationType+LimitType` 형식(예: `TableWriteAccountLimitExceeded` 또는 `IndexReadAccountLimitExceeded`)과 영향을 받은 리소스의 ARN을 따릅니다. 이를 통해 스로틀된 리소스(테이블 또는 인덱스)가 무엇인지, 어떤 작업 유형(읽기 또는 쓰기)가 스로틀링을 유발했는지, 계정 수준 서비스 할당량을 초과했는지를 확인할 수 있습니다. 스로틀링 문제 진단 및 해결에 대한 자세한 내용은 [스로틀링 진단](throttling-diagnosing-workflow.md) 섹션을 참조하세요.  
예: 온디맨드 요청량이 허용된 계정 처리량을 초과했으며 더 이상 테이블의 크기를 조정할 수 없습니다.  
재시도 가능? 예

**ResourceInUseException**  
메시지: *변경하려는 리소스가 현재 사용 중입니다. *   
예: 기존 테이블을 다시 생성하려고 하거나, 또는 현재 `CREATING` 상태인 테이블을 삭제하려고 했습니다.  
재시도 가능? 아니요

**ResourceNotFoundException **  
메시지: *요청한 리소스를 찾을 수 없습니다.*  
예제: 요청한 테이블이 존재하지 않거나 너무 일찍 `CREATING` 상태가 되었습니다.  
재시도 가능? 아니요

**ThrottlingException**  
메시지: *요청량이 허용 처리량을 초과하였습니다.*  
이 예외는 THROTTLING\$1EXCEPTION 상태 코드와 함께 AmazonServiceException 응답으로 반환됩니다. [제어 플레인](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.ControlPlane) API 작업을 너무 빠르게 수행하는 경우 이 예외가 반환될 수 있습니다.  
요청 속도가 너무 높으면 온디맨드 모드를 사용하는 테이블의 경우 모든 [데이터 플레인](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html#HowItWorks.API.DataPlane) API 작업에 대해 이 예외가 반환될 수 있습니다. 온디맨드 규모 조정에 대한 자세한 내용은 [초기 처리량 및 규모 조정 속성](on-demand-capacity-mode.md#on-demand-capacity-mode-initial) 섹션을 참조하세요.  
오류에는 스로틀링이 발생한 구체적인 원인을 설명하는 `ThrottlingReason` 필드 목록이 포함되어 있으며, `ResourceType+OperationType+LimitType` 형식(예: `TableReadKeyRangeThroughputExceeded` 또는 `IndexWriteMaxOnDemandThroughputExceeded`)과 영향을 받은 리소스의 ARN을 따릅니다. 이 정보는 어떤 리소스(테이블 또는 인덱스)가 스로틀되고 있는지, 어떤 작업 유형(읽기 또는 쓰기)이 스로틀링을 유발했는지, 초과된 특정 한도(파티션 한도 또는 온디맨드 최대 처리량)를 식별하는 데 도움이 됩니다. 스로틀링 문제 진단 및 해결에 대한 자세한 내용은 [스로틀링 진단](throttling-diagnosing-workflow.md) 섹션을 참조하세요.  
재시도 가능? 예

**UnrecognizedClientException**  
메시지: *액세스 키 ID 또는 보안 토큰이 잘못되었습니다.*  
요청 서명이 잘못되었습니다. 가장 가능성이 높은 원인은 잘못된 AWS 액세스 키 ID 또는 보안 키입니다.  
재시도 가능? 예

**ValidationException**  
메시지: 발생하는 구체적 오류에 따라 다릅니다  
이 오류는 필수 파라미터의 누락, 값의 범위 이탈 또는 일치하지 않는 데이터 형식 등 몇 가지 이유로 발생할 수 있습니다. 오류 메시지에는 요청에서 오류를 일으킨 특정 부분에 대한 정보가 포함됩니다.  
재시도 가능? 아니요

### HTTP 상태 코드 5xx
<a name="Programming.Errors.MessagesAndCodes.http5xx"></a>

HTTP `5xx` 상태 코드는 AWS가 해결해야 하는 문제를 나타냅니다. 이것은 일시적 오류일 수 있으므로 성공할 때까지 요청을 다시 시도할 수 있습니다. 그렇지 않은 경우 [AWS Service Health Dashboard](https://status.aws.amazon.com/)에서 서비스 운영 문제가 있는지 확인하세요.

자세한 내용은 [Amazon DynamoDB에서 HTTP 5xx 오류를 해결하려면 어떻게 해야 하나요?](https://aws.amazon.com/premiumsupport/knowledge-center/dynamodb-http-5xx-errors/)를 참조하세요.

**InternalServerError (HTTP 500)**  
DynamoDB에서 요청을 처리할 수 없습니다.  
재시도 가능? 예  
항목 작업 시 내부 서버 오류가 발생할 수 있습니다. 이러한 오류는 테이블 수명 동안 예상됩니다. 실패한 요청은 즉시 다시 시도할 수 있습니다.  
쓰기 작업에 대한 상태 코드 500을 수신하면 작업이 성공했거나 실패했을 수 있습니다. 쓰기 작업이 `TransactWriteItem` 요청이면 작업을 다시 시도해도 좋습니다. 쓰기 작업이 `PutItem`, `UpdateItem` 또는 `DeleteItem` 같은 단일 항목 쓰기 요청인 경우 작업을 다시 시도하기 전에 애플리케이션이 항목의 상태를 읽어야 합니다. 그리고 [DynamoDB 조건 표현식 CLI 예제](Expressions.ConditionExpressions.md)를 사용하여 이전 작업의 성공 여부와 관계없이 재시도한 후에도 항목이 올바른 상태로 유지되도록 해야 합니다. 멱등성이 쓰기 작업의 요구 사항인 경우 동일한 작업을 수행하려는 여러 시도를 명확하게 하기 위해 `ClientRequestToken`을 자동으로 지정하여 멱등원 요청을 지원하는 [`TransactWriteItem`](transaction-apis.md#transaction-apis-txwriteitems)을 사용하세요.

**ServiceUnavailable (HTTP 503)**  
DynamoDB를 현재 사용할 수 없습니다. (이것은 일시적 상태여야 합니다.)  
재시도 가능? 예

## 애플리케이션에서의 오류 처리
<a name="Programming.Errors.Handling"></a>

애플리케이션의 원활한 실행을 위해서는 오류를 발견하고 대응할 수 있는 로직을 추가해야 합니다. 일반적인 접근법에는 `try-catch` 블록 또는 `if-then` 문의 사용이 포함됩니다.

AWS SDK는 자체적으로 재시도 및 오류 검사를 수행합니다. AWS SDK 사용 중에 오류가 발생하면 해당 오류 코드와 설명이 문제 해결에 도움이 될 수 있습니다.

또한 응답에서 `Request ID`도 확인해야 합니다. 문제 진단을 위해 AWS Support와 협력해야 하는 경우 `Request ID`가 도움이 될 수 있습니다.

## 오류 재시도 횟수 및 지수 백오프
<a name="Programming.Errors.RetryAndBackoff"></a>

DNS 서버, 스위치, 로드 밸런서 등 수많은 네트워크 구성 요소는 요청이 이루어지는 모든 단계에서 오류를 일으킬 수 있습니다. 네트워크 환경에서는 클라이언트 애플리케이션의 재시도 기술이 이러한 오류 응답을 처리하는 데 가장 많이 사용되고 있습니다. 이 기술은 애플리케이션의 안정성을 개선합니다.

AWS SDK는 모두 재시도 로직을 자동으로 구현합니다. 재시도 파라미터를 필요에 따라 수정할 수 있습니다. 예를 들어 오류가 발생할 때 재시도가 허용되지 않는 fail-fast 전략을 필요로 하는 Java 애플리케이션을 고려해 보세요. AWS SDK for Java의 경우, `ClientConfiguration` 클래스를 사용하고 `maxErrorRetry` 값으로 `0`을 입력하면 재시도가 비활성화됩니다. 자세한 내용은 해당 프로그래밍 언어의 AWS SDK 설명서를 참조하세요.

AWS SDK를 사용하지 않을 때는 서버 오류(5xx)가 수신된 최초 요청을 재시도해야 합니다. 하지만 클라이언트 오류(4xx, `ThrottlingException` 또는 `ProvisionedThroughputExceededException` 제외)는 요청 자체를 수정하여 문제를 해결해야만 재시도가 가능합니다. 특정 스로틀링 시나리오를 해결하기 위한 자세한 권장 사항은 [DynamoDB 제한 문제 해결](TroubleshootingThrottling.md) 섹션을 참조하세요.

간단한 재시도 방법 외에도 각각의 AWS SDK는 흐름 제어가 탁월한 지수 백오프 알고리즘을 구현합니다. 지수 백오프의 기본 개념은 오류 응답이 연이어 나올 때마다 재시도 간 대기 시간을 점진적으로 늘린다는 것입니다. 예를 들어 첫 번째 재시도 전에는 최대 50밀리초, 두 번째 재시도 전에는 최대 100밀리초, 그리고 세 번째 전에는 최대 200밀리초를 기다리는 방식입니다. 하지만 1분 후에도 요청이 실패하면 요청량이 아니라 할당 처리량을 초과하는 요청 크기가 원인일 수도 있습니다. 따라서 약 1분 정도에서 멈추도록 최대 재시도 횟수를 설정하세요. 요청이 실패하면 프로비저닝된 처리량 옵션을 살펴보는 것이 좋습니다.

**참고**  
AWS SDK는 자동 재시도 로직과 지수 백오프를 구현합니다.

대부분의 지수 백오프 알고리즘은 지터(임의 지연)를 사용하여 연쇄 충돌을 방지합니다. 이 경우에는 이런 충돌을 방지하는 것이 아니므로 이 난수를 사용할 필요가 없습니다. 하지만 동시 클라이언트를 사용하는 경우에는 지터가 보다 빠른 요청 성공에 도움이 될 수 있습니다. 자세한 내용은 [지수 백오프 및 지터](http://www.awsarchitectureblog.com/2015/03/backoff.html) 블로그 게시물을 참조하세요.

## 일괄 작업 및 오류 처리
<a name="Programming.Errors.BatchOperations"></a>

DynamoDB 하위 수준 API는 읽기와 쓰기에 대한 배치 작업을 지원합니다. `BatchGetItem`은 하나 이상의 테이블에서 항목을 읽고 `BatchWriteItem`은 하나 이상의 테이블에 항목을 추가하거나 삭제합니다. 이 배치 작업은 다른 배치가 아닌 DynamoDB 작업 주위의 래퍼로 구현됩니다. 즉, `BatchGetItem`은 각 항목마다 한 번씩 `GetItem`을 일괄 방식으로 불러옵니다. 마찬가지로 `BatchWriteItem`은 각 항목마다 상황에 맞게 `DeleteItem` 또는 `PutItem`을 일괄 방식으로 불러옵니다.

배치 작업은 처리 도중 개별 요청의 오류를 허용할 수 있습니다. 예를 들어 `BatchGetItem` 요청으로 항목 5개를 읽어온다고 가정하겠습니다. 이때 기본 `GetItem` 요청 일부가 실패하더라도 전체 `BatchGetItem` 작업이 실패하지는 않습니다. 그러나 5개 읽기 작업 모두 실패하면 전체 `BatchGetItem`이 실패합니다.

배치 작업은 실패한 요청 각각에 대한 정보를 반환하므로 사용자가 문제를 진단하고 작업을 재시도할 수 있습니다. `BatchGetItem`의 경우 해당하는 테이블 및 기본 키가 응답의 `UnprocessedKeys` 값으로 반환됩니다. `BatchWriteItem`에서도 비슷한 정보가 `UnprocessedItems`로 반환됩니다.

읽기 또는 쓰기 작업이 실패할 수 있는 가장 큰 원인은 *병목 현상*입니다. `BatchGetItem`일 때는 일괄 요청에 포함된 하나 이상의 테이블에 작업을 지원할 만큼 충분한 읽기 용량이 할당되지 않은 경우입니다. 그리고 `BatchWriteItem`일 때는 하나 이상의 테이블에 충분한 쓰기 용량이 프로비저닝되지 않은 경우입니다.

DynamoDB가 미처리 항목을 반환하면 해당 항목에 대해 배치 작업을 재시도해야 합니다. 하지만 *지수 백오프 알고리즘 사용을 강력히 권장합니다*. 배치 작업을 바로 재시도하면 각 테이블의 병목 현상으로 인해 원인이 된 읽기 또는 쓰기 요청이 다시 실패할 수 있습니다. 하지만 지수 백오프를 사용하여 배치 작업을 지연시키면 일괄에 포함된 각 요청 작업이 성공할 가능성이 훨씬 높습니다.

**참고**  
일부 AWS SDK는 처리되지 않은 항목 재시도를 자동으로 처리하는 상위 수준 클라이언트를 제공하므로 이 재시도 로직을 직접 구현할 필요가 없습니다. 예제:  
**Java** - 배치 작업을 수행할 때 AWS SDK for Java v2의 [DynamoDB Enhanced Client](DynamoDBEnhanced.md)와 v1의 [DynamoDBMapper](DynamoDBMapper.md)가 모두 처리되지 않은 항목을 자동으로 재시도합니다.
**Python** - boto3 Table 리소스 `batch_writer`는 배치 쓰기 작업에 대해 처리되지 않은 항목 재시도를 묵시적으로 처리합니다. 자세한 내용은 [batch\$1writer 테이블 리소스 사용](programming-with-python.md#programming-with-python-batch-writer) 섹션을 참조하세요.
하위 수준 클라이언트 또는 이 동작을 제공하지 않는 SDK를 사용하는 경우 위에서 설명한 대로 재시도 로직을 직접 구현해야 합니다.