Showing posts with label dynamo. Show all posts
Showing posts with label dynamo. Show all posts

Tuesday, January 06, 2015

Amazon DynamoDB - Global Secondary Index (GSI)

[什麼是GSI]
Global Secondary Index跟Local Secondary Index很類似,
都是讓你可以在原有的table上選擇另一組key來幫助資料查詢.
不過GSI的彈性更大, Hash key可以是任意的attribute, 也可以跟原本的table的schema不同.
LSI只能用在原本是Hash-Range key的table,
GSI則是Hash/Hash-Range key都可以, 其所建立的index也不一定要有Range key.
但還是只能選擇單一值的attribute當key.

[對throughput的影響]
與LSI不同, GSI並不會佔用原本table的throughput,
而是需要另外指定專屬於那個index的throughput.
因為我們並不會直接寫入資料到GSI, 而是在我們新增修改刪除原始table的時候,由DynamoDB主動更新GSI的資料.
所以就是用更新的頻率來預估計寫入的throughput,
讀取的throughput就是看你的使用情境
另外, 讀取GSI的資料只能是eventually consistent哦!

ref:
- Global Secondary Index

Amazon DynamoDB:
- Local Secondary Index

Monday, January 05, 2015

Amazon DynamoDB - Local Secondary Index (LSI)

在某些情況下, 我們所定義的(Hash/Hash-Range)key並不能滿足所有查詢資料的使用情境,
這時候我們可能會利用Query加上特定的filter,或是利用Scan來找到符合的資料,
但這兩種方法不僅沒有效率(不能保證幾次來回才能拿到所有結果)我們也難以掌握需要消耗多少throughput
我們也可以用額外的table記錄相同的資料但選擇不同的key來滿足各種查詢情境,
但是要維持每個寫入都要完整更新到各個table並不是件容易的事.

為了解決這個問題, DynamoDB提供了Local Secondary Index(LSI), 其實已經推出好一段時間囉XD

[什麼是LSI]
在原本的Hash-Range key之外, 能夠利用原本的Hash key搭配其他的attribute作為新的Hash-Range key來幫助各種可能發生的查詢.
- 選擇的attribute必須是單一值不能是集合
- 此attribute的值不需要是唯一
- 寫入還是針對原本的Hash-Range key, DynamoDB會根據設定更新LSI的資料

[注意事項]
- 一個table最多只能設定五組LSI
- 可以選擇哪些其他的attribute要一起被複製進LSI(原本的Range key一定會被加進去)
- 同一個Hash key底下最多只能掛10GB的資料量, 所以得要在便利性以及資料大小間取得平衡

[對throughput的影響]
- 對LSI的讀寫是消耗整個table的throughput
- 除了10GB的限制會讓我們需要取捨要複製哪些attribute進LSI, 另外要考慮的就是資料越大讀寫時需要的throughput就越大啦
- 如果寫入會影響到LSI的資料, 則會需要消耗額外的throughput:新增,更新(刪除再新增),刪除


ref:
- Local Secondary Indexes

Sunday, December 07, 2014

Amazon DynamoDB - Data Modeling and Scaling Best Practices | AWS re:Invent 2014

前情提要:
Amazon DynamoDB會將一個table切成好幾個partition,
而整個table的throughput會平均分配給各個partition.
Total provisioned throughput/partitions = throughput per partition
不過partition跟思念一樣都是很玄的東西,
Amazon DynamoDB的官方文件只輕描淡寫的說是依照hash key來決定item是屬於哪個partition,
我們無從得知我們的table實際上被切成幾個partition.
然而在今年的AWS re:Invent, Amazon DynamoDB: Data Modeling and Scaling Best Practices的講者終於揭開了partition的奧秘!
剛剛查了一下官方文件不知何時也更新囉!
Partition的個數跟table的資料量(大小)以及讀寫的provision throughput有關.
若是你的RCU和WCU都是1000,
( 1000 / 3000 ) + ( 1000 / 1000 ) = 1.333
那你的table就會需要兩個partition, 分別有500的RCU和WCU.

依照公式可以看出,
若是我們的資料量不大而且需要的讀寫量(單筆資料&頻率)不高,
其實table是不會被切成多個partition哦!.
所以不用擔心存取資料(key)不夠分散, 某些狀況下可以好好利用這點.

另外講者也提到一些實際應用上的小技巧,
針對熱門的read item像是拍賣主打的商品資料要cache來降低花費(減少需要的throughput)
針對熱門的write item像是投票系統的候選人則是要自行把候選人切成多個key讓寫入能夠分散
(投票的人數多過於候選人, 且票數常常是集中在固定幾個人身上)

不錯的影片, 有在用DynamoDB的人值得看看啦!

Wednesday, November 06, 2013

Amazon DynamoDB - 關於資料的新增修改與刪除

前篇提到Amazon DynamoDB提供BatchWriteItem讓你一次新增或刪除(修改不行)多筆資料,
不過BatchWriteItem並不像單一PutItem/DeleteItem能透過設定檢查條件來決定操作是否合法,
於是就得要先用BatchGetItem將資料抓出來自行過濾後再把該新增或刪除的東西丟過去.


如果是要修改的話就只能用UpdateItem來做囉!
以下就是UpdateItem(有些參數是PutItem跟DeleteItem也能用的)的小心得

[Request - Action] 用來指定該如何更新這筆資料
有PUT, DELETE, and ADD三種方式而最終結果會跟這筆資料(指定的primary key)是否存在相關
1. Primary key存在
- PUT: 舊資料會被新的完全取代.
- DELETE: 會把這筆資料的某個屬性(attribute)刪掉, 但如果是對某個型態為集合(Set)的屬性給定某(或多)個值, 則會把這個值從集合中移除. ex: [A,B,C] - [B] -> [A,C]
- ADD: 屬性不存在會新增, 若是存在則會失敗. 有兩個例外, 一是屬性類型為數字的情況下會將給定的加上去, 若類型為集合則會將值加入集合中.
2. Primary key不存在
- PUT: 就是新增資料.
- DELETE: 沒事.
- ADD: 在屬性類型為數字或集合的情況會資料

[Request - Expected] 用來指定你希望在什麼條件下這個操作會成功
1. 存在(Exists)條件為否, 操作就只有在給定的屬性不存在的情況下才會成功.
2. 存在(Exists)條件為真, 操作就只有在給定的屬性等於某個值(不能不檢查值真的很煩)的情況下才會成功.

[Response - ReturnValues] 能順便讀取全部或部份資料
有NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW五種選擇.
1. NONE - 不回傳.
2. ALL_OLD - 回傳UpdateItem執行前完整的資料.
3. UPDATED_OLD - 回傳這個屬性更新前的值.
4. ALL_NEW - 回傳UpdateItem執行前完整的資料.
5. UPDATED_NEW - 回傳這個屬性更新後的值.

有一點是文件上沒特別提到的, 若是有指定回傳值那此次UpdateItem的所消耗的CapacityUnits會加倍(就是一個request同時讀寫的計價法, Amazon完全不讓自己虧到XD)哦!

我想這大概是最後一篇了吧XD
越用越覺得DynamoDB限制多多(所以這其實是抱怨文來著)
不過也沒想到寫了四篇(第一篇還是四月勒),
其實邊寫邊覺得很彆扭, 英文的文件吸收完在用中文寫出來怎麼都覺得不順啊!
而且很多字不知道該不該硬翻成中文, 就變成這樣中英夾雜的狀態.(汗)


前三集:
Amazon DynamoDB - 踏出第一步
Amazon DynamoDB - 使用table的最高指導原則
Amazon DynamoDB - 注意事項

Sunday, September 15, 2013

Amazon DynamoDB - 注意事項

之前有講到你需要根據預估的使用者情境來決定table要怎麼設計以及讀寫throughput,
其實還有一些Dynamo本身的限制是我們在設計table時也需要列入考量的,

參考文件: Limits in Amazon DynamoDB


[資料的限制]
1. Item size: 單一筆資料的大小限制
- 64KB, 各別資料的attribute名稱跟值總和不能超過64K

2. Hash primary key attribute value: Hash key值的大小限制
- 2048 bytes

3. Range primary key attribute value: Range key值的大小限制
- 1024 bytes

4. Hash or hash-and-range primary key(Number of hash key values): Hash key的個數限制
- 一個table可以存放無限個hash key

5. Hash-and-range primary key(Number of range keys per hash value): Range key的限制
- 針對有設定local secondary index的table, 同一個hash key底下的range key, 其整體item的大小(原始table加上index table)不能超過10 GB

6. Maximum number of values in an attribute set: 單一筆資料能放的attribute個數限制
- 只要單一資料整體大小在64KB以內, 要有幾個attribute都可以.


[存取行為限制]
1. BatchGetItem
- 一次最多只能抓1MB以內的資料, 最多是100個item
- 如果超過這次能處理的量, response內會提供有UnprocessedKeys讓你可以在下一輪處理
- request可以跨不同的table

2. BatchWriteItem
- 一次最多只能新增或刪除1MB以內的資料, 最多是25個item
- 不支援資料更新
- 如果超過這次能處理的量, response內會提供有UnprocessedKeys讓你可以在下一輪處理
- request可以跨不同的table

3. Query
- 一次最多只能抓1MB以內的資料
- 如果超過這次能處理的量, response內會提供有LastEvaluatedKey讓你可以在下一輪處理
- 可以用ScanIndexForward來指定query的順序

4. Scan
- 一次最多只能檢查1MB以內的資料
- 如果超過這次能處理的量, response內會提供有LastEvaluatedKey讓你可以在下一輪處理
- 能夠透過切segment作Parallel Scan來加快尋找的速度


這些規則乍看起來沒什麼, 但最好要謹記在心
如果你有一個資料會越長越大(像是要記一個使用者買過甚麼東西),
那就千萬不能把他塞在只有hash key(用使用者ID)的table裡,(還記得64KB的限制嗎?)
要再加上range key(用購買時間或交易編號)把每一筆子資料拆開
大概就是這樣囉!

前兩集:
Amazon DynamoDB - 踏出第一步
Amazon DynamoDB - 使用table的最高指導原則

Thursday, May 09, 2013

Amazon DynamoDB - 使用table的最高指導原則

只要開好table, 依照預期的使用情境設定需要的throughput, service就能夠完美運轉了嗎?
嗯... 不完全是
如果你的primary key選擇不當或是table的讀寫過度集中在某幾個item的話,
系統很可能會達不到provisioned throughput

以下是你需要特別注意的:

[1] 讓讀寫平均分散在整個table
Amazon DynamoDB會將一個table切成好幾個partition, 而整個table的throughput會平均分配給各個partition.
Total provisioned throughput/partitions = throughput per partition
不過partition跟思念一樣都是很玄的東西
Amazon DynamoDB的官方文件只輕描淡寫的說是依照hash key來決定item是屬於哪個partition
我們無從得知我們選擇的key是否適當以及table實際上被切成幾個partition
如果table整體的read throughtput是100, 而你的讀取永遠都是落在四個partition中的同一個,
那你對這個table實際上read throughput其實只有25啊!
這是相當嚴重的問題, 錢可不能白花(插腰)

對此有不少人在forum提出相關的問題
* Partition size/key range info
* DynamoDB Hash key partition strategy
** DynamoDB currently does not expose information about the number of individual partitions, their size, and the location of the data within them.
As such, it also does not expose any explicit control to tune how partitions are laid out.
It is all done automatically, seamlessly and behind the covers by the service on the user's behalf. This is a big part of our strategy to minimize the user's administrative costs. by Stefano@AWS
** DynamoDB will take the value you supply and hash it internally. Therefore, you do not need to worry about consecutive numbers or keys with a similar prefix.
For example, (the actual hash would be longer, but this is the idea):
hash-key value DynamoDB hash
400234 2c15fa5f1
400235 0e2805bcd
400236 0dad171e6
DynamoDB would partition these three items based on the DynamoDB hash so their placement should be spread amongst the data set. by Bjorn@AWS
看起來不需要擔心使用的hash key是連續的或是擁有相同的prefix,
而是需要考慮我們選擇的hash key是不是會讓整個table的存取不夠平均分散在各個partition.
我們至少可以做的就是讓hash key的base夠大, 降低集中存取某個partition的機率

[2] 瞭解table的存取模式是否具有時間相關性
以電子郵件為例, 通常是照時間排序來呈現所以越久以前的信件被顯示的機率就越低
與其將所有的信件都塞在同一個table, 熱門及冷門資料混雜(可能提高集中存取的可能性)
我們可以週期性的產生新的table, 將新的熱門的資料放在一起, 給予較高的throughput
並逐步調低舊table的throughput以節省花費
如果這些資料在一定的時間內會過期, 使用這個方法我們就可以用刪除整個table來取代單筆資料刪除(需要多一倍的寫入throughput)

最後的最後, 如果想知道table是否能達到設定的throughput最簡單的方法就是實際測測看!
只要在發生ThrottlingException時, 用rps搭配item大小算出throughput是否接近設定值就可以囉~
也可以直接參考cloudwatch的資料, 不過我覺得自己算卡安心

ref: Guidelines for Working With Tables

更新: Amazon DynamoDB - Data Modeling and Scaling Best Practices | AWS re:Invent 2014

Sunday, April 07, 2013

Amazon DynamoDB - 踏出第一步

Amazon DynamoDB是一種Key-Value NoSQL的資料庫服務.
並且能夠透過簡易的設定來動態調整你所需要的目標throughtput.

不過事情不是字面上看起來那麼容易,
實際上是你必須要對DynamoDB的設計邏輯有一些瞭解,
才能讓你的系統真正能夠scalable.
或是更進而讓你抓到最適合的throughput設定, 把錢花在刀口上不會造成無謂的浪費.

[1] 開table
1. table命名
命名規則: 長度在3到255之間, 合法的字元包含a-z, A-Z, 0-9, '_', '-'和'.'

2. 指定primary key
有兩種類型的primary key可供選擇, 要用哪種就看你所要儲存的資料特行來作決定.
(1). Hash Type Primary Key — primary key僅由一hash attribute構成. 就如同我們常用的Hash Table.
(2). Hash and Range Type Primary Key — primary key由兩個部份組成, 一是hash attribute, 另一個是range attribute. 可以想成是Hash Table還有subkey(即range attribute)來找到屬於同一個hash值的東西, 而range是有經過排序的.

3. 設定throughput
除了幫table命名以及選擇primary key之外,
另外還需要指定這個table的throuthput(即每秒所需的讀寫量, 要注意不是次數!)
Amazon就是依照throughput來收費.
(1) Read capacity units — 單位是每秒對1KB大的資料有多少次consistent的讀取.
(2) Write capacity units — 單位是每秒對1KB大的資料有多少次寫入.

[2]如何計算不同Operation所需要的Capacity
由上面的定義可以知道影響throughput的因素有三個:
1. Item size: 資料大小, 計算方式為attribute名稱及value長度的總和

(1) get: 用來取符合primary key的item
計算單位是KB, 採用無條件進入(低消是1KB 囧)不是四捨五入
(2) batch get: 給定多個primary key, 用來一次拿取多個item, 可以跨不同table
計算方式為個別檔案分別無條件進入之後再加總
(3) query: 只能針對hash-and-range primary key table, 必須給定hash key並且對range下條件, 最多一次回1MB
計算方式為符合條件的結果全部加總再無條件進入
(4) scan: 可利用任意條件來尋找符合的item, 最多一次回1MB
計算方式為在scan過程中曾經被用來比較的所有item的大小, 過程中最多只會比較到累積1MB大的資料, 再回傳符合的項目
(5) put: 新增或完全取代原有的item
計算方式以新/舊item較大的size來算
(6) update: 修改已存在的item
計算方式以新/舊item較大的size來算
(7) delete: 刪除符合primary key的item
計算方式為此item的size

2. Expected read and write request rates: 預期的讀寫次數, 就是看你的使用情境以及架構設計而定囉~

3. Consistency: 資料的一致性
Amazon DynamoDB為了保證資料的可獲得性, 針對每個item都會有多份複製.
每次的寫入都會更新每個複製, 但這個步驟是需要花時間的.
很可能在讀取時, 你拿到的那份複製尚未被更新.
對此, Amazon DynamoDB有兩種資料一制性的設定以供選擇
(1) Eventually consistent read
當你讀取(get, batch get, query or scan)時, 如果之前不久有個寫入, 可能會拿到不是最新的資料.
但是稍候(通常會在1秒內)再次讀取就能夠獲得最近的更新.
讀取預設都是eventually consistent, 但有些operation可以指定為consistent read.
(2) Consistent read
當你讀取(僅限get和query)時, 一定會拿到最新的資料.
在計算read capacity unit時, 是以consistent read來計算,
若你是採用eventually consistent則只需要1/2的provision throughput

以下是簡單的範例:
Expected Item Size Consistency Desired Reads Per Second Provisioned Throughput Required
2KB Consistent 50 100
4KB Eventually Consistent 50 100

下回見