DynamoDB 错误处理 - Amazon DynamoDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

DynamoDB 错误处理

本节描述运行时系统错误,以及如何处理它们。它还描述特定于 Amazon DynamoDB 的错误消息和代码。有关适用于所有 Amazon 服务的常见错误列表,请参阅访问管理

错误组成部分

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

如果请求失败,DynamoDB 会返回一个错误。每个错误包含三个部分:

  • HTTP 状态代码(如 400)。

  • 异常名称(如 ResourceNotFoundException)。

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

Amazon SDK 负责将错误传播到应用程序,以便您能执行适当操作。例如,在 Java 程序中,您可以编写 try-catch 逻辑以处理 ResourceNotFoundException

如果您使用的不是 Amazon 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 中的事务冲突处理

错误消息和代码

下面是 DynamoDB 返回的异常列表,按 HTTP 状态代码分组。如果确定重试?,则可以在此提交相同请求。如果确定重试?,则需要先解决客户端问题,然后再提交新请求。

HTTP 状态代码 400

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

AccessDeniedException

消息:访问被拒绝。

客户端未正确签名请求。如果使用 Amazon SDK,系统将自动为您签署请求;否则,请参阅《Amazon Web Services 一般参考》中的签名版本 4 签名流程

确定重试? 否

ConditionalCheckFailedException

消息:有条件请求失败。

指定条件的计算结果为 false。例如,您可能已尝试对项目执行有条件更新,但属性的实际值与条件预期值不匹配。

确定重试? 否

IncompleteSignatureException

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

请求签名未包含所有必需的部分。如果使用 Amazon SDK,系统将自动为您签署请求;否则,请参阅《Amazon Web Services 一般参考》中的签名版本 4 签名流程

确定重试? 否

ItemCollectionSizeLimitExceededException

消息:超过集合大小。

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

确定重试? 是

LimitExceededException

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

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

确定重试? 是

MissingAuthenticationTokenException

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

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

确定重试? 否

ProvisionedThroughputExceededException

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

示例:您的请求速率过高。DynamoDB 的 Amazon SDK 自动重试收到此异常的请求。除非重试队列太长以致无法完成,否则请求最终都会成功。请使用错误重试和指数回退降低请求频率,

确定重试? 是

RequestLimitExceeded

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

示例:按需请求的速率超出允许的账户吞吐量,该表无法进一步扩展。

确定重试? 是

ResourceInUseException

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

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

确定重试? 否

ResourceNotFoundException

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

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

确定重试? 否

ThrottlingException

消息:请求速率超出允许吞吐量。

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

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

确定重试? 是

UnrecognizedClientException

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

请求签名错误。最有可能的原因是 Amazon 访问密钥 ID 或密钥无效。

确定重试? 是

ValidationException

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

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

确定重试? 否

HTTP 状态代码 5xx

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

有关更多信息,请参阅如何解决 Amazon DynamoDB 中的 HTTP 5xx 错误?

InternalServerError (HTTP 500)

DynamoDB 无法处理您的请求。

确定重试? 是

注意

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

当您收到写入操作的状态代码 500 时,该操作可能已成功或失败。如果写入操作是 TransactWriteItem 请求,那么可以重试该操作。如果写入操作是单项写入请求,例如 PutItemUpdateItemDeleteItem,那么您应用程序应该在重试操作之前读取项目的状态,和/或使用 条件表达式 以确保项目在重试后保持正确的状态,无论之前的操作是成功还是失败。如果写入操作要求幂等性,请使用 TransactWriteItem,它通过自动指定 ClientRequestToken 消除多次尝试执行同一操作的歧义,从而支持幂等性请求。

ServiceUnavailable (HTTP 503)

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

确定重试? 是

应用程序中的错误处理

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

Amazon SDK 执行自己的重试和检查错误。如果使用某个 Amazon SDK 时遇到错误,错误代码和错误描述可帮助您纠正错误。

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

错误重试和指数回退

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

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

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

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

注意

Amazon SDK 实施自动重试逻辑和指数回退。

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

批处理操作和错误处理

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

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

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

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

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