2017-07-31 85 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