我的应用程序从DynamoDB读取数据,该数据具有预先配置的读取容量,这限制了读取吞吐量。我想控制我的查询以达不到限制,现在我正在这样做:
const READ_CAPACITY = 80
async function query(params) {
const consumed = await getConsumedReadCapacity()
if (consumed > READ_CAPACITY) {
await sleep((consumed-READ_CAPACITY)*1000/READ_CAPACITY)
}
const result = await dynamoDB.query(params).promise()
await addConsumedReadCapacity(result.foo.bar.CapacityUnits)
return result.Items
}
async function getConsumedReadCapacity() {
return redis.get(`read-capacity:${Math.floor(Date.now() / 1000)}`)
}
async function addConsumedReadCapacity(n) {
return redis.incrby(`read-capacity:${Math.floor(Date.now() / 1000)}`, n)
}
如您所见,查询将首先检查当前消耗的读取容量,如果它不超过READ_CAPACITY
,则执行查询,并累计消耗的读取容量。
问题是代码在多个服务器上运行,因此存在竞争条件,其中consumed > READ_CAPACITY
检查已通过,并且在执行dynamoDB.query
之前,dynamodb通过来自其他进程的查询来限制容量限制其他服务器。我怎样才能改善这个?
答案 0 :(得分:1)
尝试一些事情而不是避免达到容量限制......
尝试,然后退出
ProvisionedThroughputExceededException
:适用于DynamoDB的AWS开发工具包会自动重试接收此异常的请求。您的请求最终会成功,除非您的重试队列太大而无法完成。使用Error Retries and Exponential Backoff降低请求频率。
<强>突发强>
DynamoDB在每分区吞吐量配置方面提供了一些灵活性。如果您没有充分利用分区的吞吐量,DynamoDB会保留一部分未使用的容量,以便以后突发吞吐量使用。 DynamoDB目前保留最多五分钟(300秒)的未使用读写容量。在偶尔的读取或写入活动突发期间,这些额外的容量单位可以非常快速地消耗 - 甚至比您为表定义的每秒预配置吞吐量容量更快。
DynamoDB Auto Scaling
来自Managing Throughput Capacity Automatically with DynamoDB Auto Scaling:
DynamoDB自动扩展使用AWS Application Auto Scaling服务代表您动态调整预配置吞吐量,以响应实际流量模式。这使得表或全局二级索引能够增加其配置的读写容量,以处理流量的突然增加,而无需限制。当工作负载减少时,Application Auto Scaling会降低吞吐量,因此您无需支付未使用的预配置容量。
在SQS中缓存
一些AWS客户实施了一个系统,如果超过吞吐量,他们会将数据存储在Amazon SQS队列中。然后,他们有一个进程从队列中检索数据,并在对吞吐量的需求较少时插入到表中。这样可以根据平均吞吐量而非峰值吞吐量来配置DynamoDB表。