使用 DynamoDB 处理中的错误 - Amazon DynamoDB

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 DynamoDB 处理中的错误

本节描述运行时错误,以及如何处理它们。它还描述特定于 Amazon DynamoDB 的错误消息和代码。

错误组件

当程序发送一个请求时,DynamoDB 会尝试处理该请求。如果该请求成功,DynamoDB 将返回一个 HTTP 成功状态代码 (200 OK) 以及来自所请求操作的结果。

如果该请求不成功,DynamoDB 将返回一个错误。每个错误包含三个部分:

  • HTTP 状态代码 (例如 400)。

  • 异常名称 (例如 ResourceNotFoundException)。

  • 错误消息 (例如 Requested resource not found: Table: tablename not found)。

这些区域有:AWS开发工具包负责将错误传播到应用程序,以便您能执行适当操作。例如,在 Java 程序中,您可以编写 try-catch 逻辑以处理 ResourceNotFoundException

如果您没有使用AWS开发工具包中,您需要分析来自 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 状态代码分组)。如果 OK to retry?Yes,则可重新提交相同的请求。如果 OK to retry? (可以重试?)No (否),则您需要先解决客户端上的问题,然后再提交新请求。

HTTP 状态代码 400

HTTP 400 状态代码表示与请求相关的问题,例如身份验证失败、缺少必需的参数或者超出预置的表吞吐量。您必须先解决应用程序中存在的问题,然后再重新提交请求。

AccessDeniedException

消息:访问遭拒绝。

客户端未正确为请求签名。如果使用的是AWSSDK,请求将自动为您签名;否则,请转到签名版本 4 签名流程中的AWS一般参考

OK to retry? 否

ConditionalCheckFailedException

消息:有条件请求失败。

您指定了评估为 false 的条件。例如,您可能已尝试对某个项执行有条件更新,但属性的实际值与条件中的预期值不匹配。

OK to retry? 否

IncompleteSignatureException

消息:请求签名不符合AWS标准。

请求签名未包含所有必需的组件。如果使用的是AWSSDK,请求将自动为您签名;否则,请转到签名版本 4 签名流程中的AWS一般参考

OK to retry? 否

ItemCollectionSizeLimitExceededException

消息:超过集合大小。

对于包含本地二级索引的表,具有相同分区键值的项目组超过了最大大小限制(10 GB)。有关项目集的更多信息,请参阅 项目集合

OK to retry? 是

LimitExceededException

消息:指定订阅者的操作过多。

并发控制层面操作过多。表和索引的累计数量CREATINGDELETING,或者UPDATING状态不能超过 50。

OK to retry? 是

MissingAuthenticationTokenException

消息:请求必须包含有效 (已注册)AWS访问密钥 ID。

请求未包含所需的授权标头,或请求的格式不正确。请参阅 DynamoDB 低级 API

OK to retry? 否

ProvisionedThroughputExceededException

消息:已超过表或一个或更多全局二级索引的最大允许预置吞吐量。要查看预置吞吐量与占用吞吐量的性能指标,请打开Amazon CloudWatch 控制台

示例:您的请求速率过高。这些区域有:AWS适用于 DynamoDB 的开发工具包会自动对收到此异常的请求执行重试。除非您的重试队列太长以致无法完成,您的请求最终都会成功。请使用错误重试和指数退避降低请求频率,

OK to retry? 是

RequestLimitExceeded

消息:吞吐量超出您的账户的当前吞吐量限制。要请求提高限制,请联系AWS在中 Supporthttps://aws.amazon.com/support

示例:按需请求的速率超出允许的帐户吞吐量。

OK to retry? 是

ResourceInUseException

消息:您尝试更改的资源正在使用中。

示例:您尝试重新创建现有表,或删除目前位于CREATING状态。

OK to retry? 否

ResourceNotFoundException

消息:找不到请求的资源。

示例:正在请求的表不存在,或过早在CREATING状态。

OK to retry? 否

ThrottlingException

消息:请求速率超出吞吐量上限。

此异常将作为 AmazonServiceException 响应返回,并带有 THROTTLING_EXCEPTION 状态代码。如果您过快地执行控制层面 API 操作,则可能会返回此异常。

对于使用按需模式的表,如果请求速率过高,则可能会针对任何数据层面 API 操作返回此异常。要了解有关按需扩展的更多信息,请参阅峰值流量和扩展属性

OK to retry? 是

UnrecognizedClientException

消息:访问密钥 ID 或安全令牌无效。

请求签名不正确。最有可能的原因是AWS访问密钥 ID 或私有密钥。

OK to retry? 是

ValidationException

消息:根据遇到的特定错误而变化

有多种原因可能导致此错误,例如缺少必需参数,值超出范围,或者数据类型不匹配。错误消息包含有关导致错误的请求特定部分的详细信息。

OK to retry? 否

HTTP 状态代码 5xx

HTTP 5xx 状态代码表示必须由 AWS 解决的问题。这可能是临时错误,在这种情况下,您可以重试请求直到它成功。否则,请转到AWS服务运行状况控制面板以查看服务是否存在任何操作问题。

Internal Server Error (HTTP 500)

DynamoDB 无法处理您的请求。

OK to retry? 是

注意

您在处理项目时可能遇到内部服务器错误。这些错误是表的生命周期中的预期错误。可立即重试所有失败的请求。

Service Unavailable (HTTP 503)

DynamoDB 当前不可用。(这应是一种临时状态。)

OK to retry? 是

应用程序中的错误处理

为了让应用程序平稳运行,您需要添加逻辑以抓取和响应错误。典型的方法包括使用 try-catch 块或 if-then 语句。

这些区域有:AWS开发工具包自己也会重试和检查错误。如果您在使用某个AWS开发工具包、错误代码和错误描述可帮助您纠正错误。

您还应该会在响应中看到 Request ID。这些区域有:Request ID可能会很有用,如果您需要使用AWSSupport 诊断问题。

以下 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 结构处理两种不同的异常:

  • AmazonServiceException-如果客户端请求正确地传输到 DynamoDB,但 DynamoDB 无法处理请求,而是返回错误响应,引发。

  • AmazonClientException-如果客户端无法从服务获得响应或者客户端无法解析来自服务的响应,引发。

错误重试和指数退避

网络上的大量组件(例如 DNS 服务器、交换机、负载均衡器等)都可能在某个指定请求生命周期中的任一环节出现问题。在联网环境中,处理这些错误回应的常规技术是在客户应用程序中实施重试。此方法提高应用程序的可靠性。

EACHAWS开发工具包将自动实施重试逻辑。您可以修改重试参数以满足您的需求。例如,考虑一个需要 fail-fast 策略的 Java 应用程序,并且在出错时不允许重试。利用AWS SDK for Java,您可以使用 ClientConfiguration 类并提供 maxErrorRetry0 来禁用重试。有关更多信息,请参阅 。AWS适用于您的编程语言的开发工具包文档。

如果您没有使用AWS开发工具包,则应当对收到服务器错误 (5xx) 的原始请求执行重试。但是,客户端错误(4xx,不是 ThrottlingExceptionProvisionedThroughputExceededException)表示您需要对请求本身进行修改,先修正了错误然后再重试。

除了简单的重试之外,每个AWS开发工具包实施指数退避算法来实现更好的流程控制。指数回退的原理是对于连续错误响应,重试等待间隔越来越长。例如,第一次重试最多等待 50 毫秒,第二次重试最多等待 100 毫秒,第三次重试最多等待 200 毫秒,依此类推。但是,如果过段时间后,请求仍然失败,则出错的原因可能是因为请求大小超出预置吞吐量,而不是请求速率的问题。您可以设置最大重试次数,在大约一分钟的时候停止重试。如果请求失败,请检查您的预置吞吐量选项。

注意

这些区域有:AWS开发工具包实施自动重试逻辑和指数退避。

大多数指数回退算法会利用抖动 (随机延迟) 来防止连续的冲突。由于在这些情况下您并未尝试避免此类冲突,因此无需使用此随机数字。但是,如果使用并发客户端,抖动可帮助您更快地成功执行请求。有关更多信息,请参阅有关指数回退和抖动的博文。

批量操作和错误处理

DynamoDB 低级 API 支持读取和写入的批处理操作。BatchGetItem从一个或多个表中读取项目,BatchWriteItem将放置或删除一个或多个表中的项目。这些批量操作作为其他非批量 DynamoDB 操作的包装得以实现。换句话说,BatchGetItem 为批处理中的每个项目调用 GetItem 一次。同样,BatchWriteItem 根据需要为批处理中的每个项目调用 DeleteItemPutItem

批量操作可以容忍批处理中的个别请求失败。举例来说,假设一个 BatchGetItem 请求读取五个项目。即使某些底层 GetItem 请求失败,这也不会导致整个 BatchGetItem 操作失败。但是,如果所有五个读取操作都失败,则整个 BatchGetItem 失败。

批量操作会返回有关各失败请求的信息,以便您诊断问题并重试操作。对于 BatchGetItem,在响应的 UnprocessedKeys 值中会返回有问题的表和主键。对于 BatchWriteItem,在 UnprocessedItems 中返回类似信息。

造成读取失败或写入失败的最可能原因是限制。对于 BatchGetItem,原因是批量请求中的一个或多个表没有足够的预置读取容量来支持操作。对于 BatchWriteItem,原因是一个或多个表没有足够的预置写入容量。

如果 DynamoDB 返回了任何未处理的项目,应对这些项目重试批量操作。然而,我们强烈建议您使用指数回退算法。如果立即重试批量操作,底层读取或写入请求仍然会由于各表的限制而失败。如果使用指数回退延迟批量操作,批处理中的各请求成功的可能性更大。