Amazon DynamoDB
开发人员指南 (API Version 2012-08-10)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

错误处理

本节描述运行时错误,以及如何处理它们。它还描述特定于 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 的低级响应的内容。以下是此类响应的示例:

Copy
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

消息:访问被拒绝。

客户端未正确为请求签名。如果您使用的是 AWS 开发工具包,则将自动对请求进行签名;否则,请转至 AWS General Reference 中的签名版本 4 签名流程

OK to retry? 否

ConditionalCheckFailedException

消息:有条件请求失败。

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

OK to retry? 否

IncompleteSignatureException

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

请求签名未包含所有必需的组件。如果您使用的是 AWS 开发工具包,则将自动对请求进行签名;否则,请转至 AWS General Reference 中的签名版本 4 签名流程

OK to retry? 否

ItemCollectionSizeLimitExceededException

消息:超过集合大小。

对于包含local secondary index的表,具有相同分区键值的项目组超过了最大大小限制 10GB。有关项目集的更多信息,请参阅 项目集合

OK to retry? 是

LimitExceededException

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

并发控制层面操作过多。处于 CREATINGDELETINGUPDATING 状态的表和索引的累计数目不能超过 10。

OK to retry? 是

MissingAuthenticationTokenException

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

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

OK to retry? 否

ProvisionedThroughputExceededException

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

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

OK to retry? 是

ResourceInUseException

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

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

OK to retry? 否

ResourceNotFoundException

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

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

OK to retry? 否

ThrottlingException

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

如果执行以下任一操作的速度太快,则可能返回此异常:CreateTableUpdateTableDeleteTable

OK to retry? 是

UnrecognizedClientException

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

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

OK to retry? 是

ValidationException

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

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

OK to retry? 否

HTTP 状态代码 5xx

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

内部服务器错误 (HTTP 500)

DynamoDB 无法处理您的请求。

OK to retry? 是

注意

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

服务不可用 (HTTP 503)

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

OK to retry? 是

应用程序中的错误处理

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

AWS 开发工具包自己也会重试和检查错误。如果您在使用某个 AWS 开发工具包时遇到错误,错误代码和错误描述可帮助您纠正错误。

您还应该会在响应中看到 Request ID。如果您需要使用 AWS Support 来诊断问题,则 Request ID 会很有用。

以下 Java 代码段尝试从 DynamoDB 表中删除项并执行基本错误处理。 (在此情况下,它仅向用户告知请求失败)。

Copy
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 occured communicating with DynamoDB"); System.out.println("Error Message: " + ace.getMessage()); }

在此代码段中,try-catch 结构处理两种不同的异常:

  • AmazonServiceException— 客户端请求正确地传输到 DynamoDB 但 DynamoDB 无法处理请求并返回错误响应时引发。

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

错误重试和指数退避

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

每个 AWS 开发工具包都会自动实现重试逻辑。您可以修改重试参数以满足您的需求。例如,考虑一个需要 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 返回了任何未处理的项目,应对这些项目重试批量操作。然而,我们强烈建议您使用指数回退算法。如果立即重试批量操作,底层读取或写入请求仍然会由于各表的限制而失败。如果使用指数回退延迟批量操作,批处理中的各请求成功的可能性更大。