[英]DynamoDB Scan Query and BatchGet
我們有一個Dynamo DB表結構,其中包含哈希和范圍作為主鍵。
Hash = date.random_number
Range = timestamp
如何在X和Y時間戳內獲取項目? 由於哈希鍵附加有random_number,因此必須多次觸發查詢。 是否可以提供多個哈希值和單個RangeKeyCondition。
在成本和時間方面最有效的是什么?
隨機數范圍是1到10。
如果我理解正確,那么您的表中的主鍵定義如下:
Hash Key : date.random_number
Range Key : timestamp
您必須記住的一件事是,無論您使用的是GetItem
還是Query
,都必須能夠計算應用程序中的Hash Key
,才能成功從表中檢索一個或多個項目。
將隨機數用作Hash Key
一部分很有意義,因此您的記錄可以均勻地分布在DynamoDB分區上,但是,您必須以一種方式使應用程序仍然可以在需要檢索這些數字時計算這些數字。記錄。
考慮到這一點,讓我們創建指定需求所需的查詢。 可用於從表中獲取多個項目的本機AWS DynamoDB操作是:
Query, BatchGetItem and Scan
為了使用BatchGetItem
您需要事先知道整個主鍵(哈希鍵和范圍鍵),事實並非如此。
Scan
操作實際上會遍歷表的每條記錄,我認為這對於您的要求是不必要的。
最后,使用Query
操作,您可以從表中檢索一個或多個項目,這些表將EQ
(等式)運算符應用於Hash Key
以及當您沒有整個Range Key
或需要時可以使用的許多其他運算符匹配多個。
Range Key
條件的操作員選項為: EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN
EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN
在我看來,最適合您要求的是BETWEEN
運算符,也就是說,讓我們看看如何使用所選的SDK構建查詢:
Table table = dynamoDB.getTable(tableName);
String hashKey = "<YOUR_COMPUTED_HASH_KEY>";
String timestampX = "<YOUR_TIMESTAMP_X_VALUE>";
String timestampY = "<YOUR_TIMESTAMP_Y_VALUE>";
RangeKeyCondition rangeKeyCondition = new RangeKeyCondition("RangeKeyAttributeName").between(timestampX, timestampY);
ItemCollection<QueryOutcome> items = table.query("HashKeyAttributeName", hashKey,
rangeKeyCondition,
null, //FilterExpression - not used in this example
null, //ProjectionExpression - not used in this example
null, //ExpressionAttributeNames - not used in this example
null); //ExpressionAttributeValues - not used in this example
您可能希望查看以下文章,以獲取有關DynamoDB主鍵的更多信息: DynamoDB:何時使用哪種PK類型?
問題:由於附加了random_number,我擔心的是多次查詢。 有沒有一種方法可以將這些查詢組合在一起,並一次命中dynamoDB?
您的擔心是完全可以理解的,但是,通過BatchGetItem
獲取所有記錄的唯一方法是知道要獲取的所有記錄的整個主鍵(HASH + RANGE)。 雖然最大程度地減少到服務器的HTTP往返傳輸乍看起來似乎是最好的解決方案,但該文檔實際上建議您按照自己的方式進行操作,以避免熱分區和配置吞吐量的不均勻使用:
設計跨表中項目的統一數據訪問
“由於您是對哈希鍵進行隨機化,因此每天對表的寫入會平均分布在所有哈希鍵值上;這將產生更好的並行性和更高的整體吞吐量。在給定的一天,您仍然需要查詢每個2014-07-09.N鍵(其中N是1到200),並且您的應用程序需要合並所有結果。但是,您將避免只使用一個鍵“熱”哈希鍵承擔所有工作量。”
來源: http : //docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html
這里還有一個有趣的觀點,建議在單個分區中適當地使用讀取...如果您從哈希鍵中刪除隨機數,以便一次就能獲得所有記錄,那么無論如何,您都可能會遇到這個問題如果您使用Scan
, Query
或BatchGetItem
:
查詢和掃描准則-避免突發的讀取活動
“請注意,這不僅是掃描使用的容量單位爆發問題,而且還因為掃描可能會消耗同一分區中的所有容量單位,因為掃描請求會讀取每個容量單位旁邊的項目這意味着該請求正在命中同一分區,導致其所有容量單位被消耗,並限制了對該分區的其他請求。如果讀取數據的請求已分散在多個分區中,則該操作不會限制特定的分區。”
最后,由於您正在使用時間序列數據,因此研究文檔建議的一些最佳實踐也可能會有所幫助:
了解時間序列數據的訪問模式
對於您創建的每個表,您指定吞吐量要求。 DynamoDB分配和保留資源,以持續的低延遲處理您的吞吐量需求。 在設計應用程序和表時,應考慮應用程序的訪問模式,以最有效地利用表資源。
假設您設計一個表來跟蹤客戶在您網站上的行為,例如他們單擊的URL。 您可以將表設計為具有哈希和范圍類型主鍵,其中客戶ID為哈希屬性,日期/時間為范圍屬性。 在此應用程序中,客戶數據會隨着時間無限增長。 但是,應用程序對表中所有項目的訪問方式可能顯示不均勻,其中最新客戶數據更相關,並且您的應用程序可能更頻繁地訪問最新項目,並且隨着時間的流逝這些項目被訪問的次數減少,最終,較舊的項目很少訪問。 如果這是已知的訪問模式,則可以在設計表架構時將其考慮在內。 您可以使用多個表來存儲這些項目,而不是將所有項目存儲在一個表中。 例如,您可以創建表來存儲每月或每周數據。 對於存儲最近一個月或一周中數據訪問率較高,要求更高吞吐量的表,對於存儲較舊數據的表,您可以降低吞吐量並節省資源。
您可以通過在吞吐量設置較高的一個表中存儲“熱”項,在吞吐量設置較低的另一表中存儲“冷”項來節省資源。 您只需刪除表即可刪除舊項目。 您可以選擇將這些表備份到其他存儲選項,例如Amazon Simple Storage Service(Amazon S3)。 刪除整個表比逐個刪除項要有效得多,因為刪除操作與放置操作一樣多,這實際上使寫入吞吐量增加了一倍。
來源: http : //docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.