2017-07-31 49 views
1

我的应用程序从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) 
} 

,你可以看到,查询首先会检查当前的消耗阅读能力,如果它不nt超过READ_CAPACITY,请执行查询,并累计所消耗的读取容量。

问题是代码在多个服务器上运行,所以有竞争条件,其中consumed > READ_CAPACITY检查合格,并执行dynamoDB.query,dynamodb readed从其他服务器上的其他进程的查询能力限制之前。我该如何改进?

回答

0

有些事情要尝试,而不是避免撞击容量限​​制......

试试,然后回退

DyanmoDB error handling

ProvisionedThroughputExceededException:该AWS的SDK为DynamoDB自动重试接收此异常的请求。您的请求最终会成功,除非您的重试队列太大而无法完成。减少请求的频率,使用Error Retries and Exponential Backoff

突发

Best Practices for Tables

DynamoDB提供了在每个分区可以通过供应一定的灵活性。如果没有充分利用分区的吞吐量,DynamoDB会保留一部分未使用的容量,以便以后的突发吞吐量使用率为。 DynamoDB目前保留最多五分钟(300秒)未使用的读取和写入容量。在偶尔爆发读取或写入活动期间,这些额外的容量单位可以非常快速地被消耗,甚至比您为表格定义的每秒供应吞吐量更快。

DynamoDB自动缩放

Managing Throughput Capacity Automatically with DynamoDB Auto Scaling

DynamoDB自动缩放使用AWS应用程序自动缩放服务动态调整以您的名义供应吞吐能力,响应到实际的流量模式。这使得表或全局二级索引可以增加其配置的读取和写入容量,以处理突然增加的流量,而不会受到限制。当工作负载减少时,应用程序Auto Scaling会降低吞吐量,因此您无需为未使用的预置容量支付费用。

缓存SQS

一些AWS客户已经实现,其中,如果超过产量,他们的数据存储在Amazon SQS队列的系统。然后他们有一个过程,从队列中检索数据,稍后在吞吐量需求较少时插入表中。这允许DynamoDB表基于平均吞吐量而不是峰值吞吐量

+0

谢谢!我已经考虑过这些选项,但我认为它们不太合适,原因是我需要每次查询300万个项目,如果吞吐量不受限制,会导致很大的高峰,所以我放弃了自动缩放和突发。至于尝试和补偿,如果新的查询和回退查询一起运行,这会不会导致更多的灾难? – cheetah