This page looks best with JavaScript enabled

DynamoDB Index

 ·  ☕ 3 min read

DynamoDB index

這篇想講一下用 DynamoDB 遇到的狀況,字很多但內容應該很少,比較像流水帳
前陣子工作時需要將 DynamoDB 的全部資料(包括已經存在的和未來新來的)載入進 Redshift
並在途中做一些資料處理,資料處理時需要使用到 DynamoDB 和 PostgreSQL 內的東西
DynamoDB 內的裝的是聊天的訊息,都有 partition key (chat room id) 和 sort key (unique timestamp in a chat room)

一開始想了兩種方法

第一種方法很簡單,就是 Batch processing,類似 cursor based pagination
就是每過一段時間去 DynamoDB 從 offset (cursor,可以是 partition key + sort key 的組合) 開始抓以後的資料來處理,處理成功就丟進 Redshift 並更新 offset
實作上看似很簡單,且不太需要處理失敗的情況,因為途中失敗就不要更新 offset 就好

當時想出來的另一種方法是比較複雜,如下圖,是 stream processing
要用的 service 多很多,且 service 之間溝通都要處理失敗的問題

最後還是選了這個來用,不過這不是這篇的重點,下次有機會再來把這裡面的東西寫清楚

當時其實時間只有一個禮拜左右,且現在資料量不多,Redshift 內的資料是要做分析報表的,需求沒有那麼及時,就打算用第一種方法來解決

結果剛要開始做的時候就發現 DynamoDB 的 index 好像沒什麼辦法支援這種設計

簡介一下 DynamoDB
資料庫內每一筆資料叫做 item,裡面有很多 attribute,就像是 RDB 的 row 和 column,不過每個 item 可以有不同 attribute (NoSQL)

Primary key 是在一個 table 中是 unique 的,由 partition key 或是 partition key + sort key 組成

在同一個 partition key (hash table) 中可以用 sort key (b-tree)讓資料有順序

到這邊就會發現 DynamoDB 的 query 是兩層,第一層是 hash,第二層是 b-tree,所以想要在我們的 table 內只用一個 cursor 來當作 offset 是不可能的,因為 hash table 沒有順序阿,還是必須掃過每個 entry

此時又想到一個 tricky 的方法,是建立一個 Global secondary index 然後把所有資料都塞到同一個 partition key 內,這樣就可以用 sort key 來當 cursor,不過查一查又發現 partition key 對 scalability 有超大的影響
AWS 會把相同 partitio key 下面的資料存在物理上很接近的位置,可以想像成不同 partition key 的資料會存在不同 disk 上,對單一 partition key 的 read 和 write 會有 throughput 的上限,只要把資料平均分散到不同 partition key,幾乎是沒有 scalability 的問題,可以參考下方連結
https://docs.aws.amazon.com/amazonDynamoDB/latest/developerguide/bp-partition-key-design.html

如果把每個 partition key (chat room id) 都各存一個 cursor (sort key) 呢?
會有不少 overhead,因為很多其實 partition key 其實都幾乎沒再用,但也不行刪除他,因為我們也無法確定是否會再次啟用。如此一來每次 batch process 啟動時都要去掃過他們造成 overhead

總之就是想了很多方法,還是找不到一個適合的 index 存法來有效支援第一種方法,或許就是 DynamoDB Partition key、Sort key、index 設計造成的限制,不過這些設計也讓他很容易 scale,算是一種 trade off
結果最後還是跑去用 DynamoDB stream 了

NOTE

Global Secondary Indexes

可以用另一組 partition key 和 sort key 來建 index
但 PK + SK 不需要 unique
只支援 eventual consistency

Local Secondary Indexes

依照原本 table 的 partition key,用另一個 sort key 來建 index
支援 consistent consistency
但官方不建議用這個東西就是了

建立多組 index 會讓花費增加,尤其是寫入時會是兩倍 cost (delete, write)

下面再推薦幾篇 DynamoDB 滿好懂得文章
DynamoDB 計費
https://medium.com/fcamels-notes/amazon-DynamoDB-%E7%9A%84-consumed-units-%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85-e1fbda5687b4

https://medium.com/fcamels-notes/amazon-DynamoDB-%E5%88%9D%E6%AD%A5%E4%BD%BF%E7%94%A8%E5%BF%83%E5%BE%97-c734d8445ae2

DynamoDB under the hood
https://www.youtube.com/watch?v=yvBR71D0nAQ

https://www.precisely.com/blog/big-data/big-data-101-batch-stream-processing

Share on

Marko Peng
WRITTEN BY
Marko Peng
Good man