【发布时间】:2017-05-19 07:16:12
【问题描述】:
我有近 300 个线程试图访问分配的读/写容量(5/秒)非常低的单个 DynamoDB 表。所以负载显然太高了,我从DynamoDBMapper得到ProvisionedThroughputExceededException。问题是:如何让 DynamoDBMapper 等待+重试而不是失败?
我在AmazonDynamoDBClient 上使用ExponentialBackoffStrategy,延迟时间很长(100 毫秒基础,12 次重试,因此产生:100 毫秒、200 毫秒、400 毫秒、... 409600 毫秒),但它不起作用。事实上,它立即失败。根据the docs:
ProvisionedThroughputExceededException
消息:您超出了允许的最大预置吞吐量 对于一个表或一个或多个全局二级索引。查看 预置吞吐量与消耗的性能指标 吞吐量,打开 Amazon CloudWatch 控制台。
示例:您的请求率过高。 适用于 DynamoDB 的 AWS 开发工具包 自动重试收到此异常的请求。你的申请 最终成功,除非您的重试队列太大而无法 完成。使用指数退避降低请求频率。
我做错了什么?
“太大而无法完成”是什么意思?
谢谢!
如果您想知道为什么我使用 300 个线程、分配的容量低并且可以接受较长的响应时间:通常我们使用更高的容量,我只是不希望应用程序在容量低时失败。
【问题讨论】:
-
300 个线程的 5 req/sec 容量非常非常小,无论您使用多少退避,重试队列中都会有大量请求,并且没有文档可以在重试队列中有多少请求,因此在您的情况下,IMO 非常频繁地跨越该数字,因此您会立即收到此异常,而不是队列中的最新请求,而是队列中的旧请求。最好的解决方案是将您的预置吞吐量增加到某个合理的数字,因为 5 对于 300 个线程来说太少了。
-
@AmitK:不,我不明白,抱歉。使用 300 个线程和每个线程每个请求 409600 毫秒的延迟,您每秒收到的请求少于 1 个(平均)。并且重试队列长度不能超过线程数。正确的?或者这可能是由指数备份时间间隔冲突引起的。我应该使用随机抖动吗?
标签: java multithreading amazon-web-services amazon-dynamodb