超过预置吞吐量时应该怎么做?
Posted
技术标签:
【中文标题】超过预置吞吐量时应该怎么做?【英文标题】:What should be done when the provisioned throughput is exceeded? 【发布时间】:2018-06-09 21:10:38 【问题描述】:我正在使用 AWS SDK for javascript (Node.js) 从 DynamoDB 表中读取数据。 Auto Scaling 功能在大部分时间都做得很好,并且消耗的读取容量单位 (RCU) 在一天的大部分时间里都非常低。但是,有一个在午夜左右执行的程序化作业消耗了大约 10 倍于预置 RCU 的消耗,并且由于自动缩放需要一些时间来调整容量,因此有很多受限制的读取请求。此外,我怀疑我的请求没有完成(尽管我在错误日志中找不到任何异常)。
为了处理这种情况,我考虑过使用 AWS API (updateTable) 增加预置的 RCU,但计算我的应用程序需要的 RCU 数量可能并不简单。
所以我的第二个猜测是重试失败的请求并等待自动缩放增加预置的 RCU。正如 AWS 文档和一些 Stack Overflow 答案所指出的那样(特别是关于 ProvisionedThroughputExceededException):
适用于 Amazon DynamoDB 的 AWS 开发工具包会自动重试收到此异常的请求。因此,您的请求最终会成功,除非请求太大或您的重试队列太大而无法完成。
我读过类似的问题(this one、this one 和 this one)但我仍然感到困惑:如果请求太大或重试队列太大而无法完成,是否会引发此异常(因此在自动重试之后)还是实际上在重试之前?
最重要的是:这是我在我的上下文中应该期待的例外吗? (所以我可以抓住它并重试,直到自动缩放增加 RCU?)
【问题讨论】:
【参考方案1】:是的。
每次您的应用程序发送超出您容量的请求时,您都会收到来自 Dynamo 的 ProvisionedThroughputExceededException 消息。但是,您的 SDK 会为您处理并重试。默认Dynamo重试时间从50ms开始,默认重试次数为10,默认退避为指数。
这意味着您可以在以下位置重试:
50 毫秒 100 毫秒 200 毫秒 400 毫秒 800ms 1.6s 3.2s 6.4s 12.8s 25.6s如果在第 10 次重试后您的请求仍未成功,SDK 会将 ProvisionedThroughputExceededException 传递回您的应用程序,您可以随意处理。
您可以通过增加吞吐量配置来处理它,但另一种选择是在创建 Dynamo 连接时更改默认重试时间。例如
new AWS.DynamoDB(maxRetries: 13, retryDelayOptions: base: 200);
这意味着您重试 13 次,初始延迟为 200 毫秒。这将使您的请求总共需要 819.2 秒而不是 25.6 秒才能完成。
【讨论】:
那么,实际上可以做些什么来避免这种情况呢?我应该远离“按需”供应吗?是这个问题吗? 当被问到这个问题时,按需供应并不存在。是的,在大多数情况下,您可能希望使用按需配置(除非您有大量且相当一致的使用)。按需,在大多数情况下,完全消除了这个问题。如果您的使用量急剧增加,超出了按需表的扩展能力,理论上仍然会发生这种情况。 我相信可能是这样。我正在迭代表中的所有记录,从这些记录中删除一个字段。 @F_SO_K 你能展示如何在 python 3.7 中进行此配置更新吗? 如前所述,如果负载从一分钟到另一分钟大幅增加,按需或预置容量仍会发生这种情况。您必须实现自己的“启动”逻辑才能完全避免这种情况。以上是关于超过预置吞吐量时应该怎么做?的主要内容,如果未能解决你的问题,请参考以下文章