現場で使えるDynamoDB
と冪等デザインパターン
2015.10.30 Yusuke Arai, Classmethod Inc.
自己紹介
• 荒井祐輔 (モバイルアプリサービス部)
• 2014.11 AndroidチームにJOIN
• 2015.04 モバイルバックエンドのScalaチームにJOIN
• Scala や API Gateway のブログをよく書いてます
• 普段は Amazon DynamoDB を Scala から JavaSDK を介
して使用しています
現場で使えるDynamoDB
と冪等デザインパターン
むしろ
もっと使おう!
DynamoDB
冪等だってあるんだよ!
今回のもくろみ
もっとラフに
DynamoDB を
使ってほしい
使ってみたいけど
何ができて
何ができないのか
よくわからない
使いたいけど
個人アプリだから
マネーが…
とりあえず
RDSで…
高可用性・高堅牢性
以外にも
DynamoDB を
使うべき
理由があります!
•DynamoDBってなんだ
•できること/できないこと
•もっと使うために
アジェンダ
•DynamoDBってなんだ
•できること/できないこと
•もっと使うために
アジェンダ
DynamoDB
KVS
NoSQL
スケーラブル
かつ
スキーマレス
1アイテム
64KBまで
可能
フルマネージド
Capacity
Unit
単位で課金
10書き込みユニット
秒間10書き込み
5.5 米ドル / 月
50読み込みユニット
= 秒間50読み込み
5.5 米ドル / 月
•DynamoDBってなんだ
•できること/できないこと
•もっと使うために
アジェンダ
できること
Keyに対する
ValueのCRUD
簡単なクエリやオーダー
できぬこと
JOIN
TRANSACTION
AND
COMMIT
詳細なクエリやオーダー
マネーが
かかること
大量のRead/Write
• できぬこと
• JOIN
• TRANSACTION AND COMMIT
• 詳細なクエリやオーダー
• マネーがかかること
• 大量のRead/Write
• できぬこと
• JOIN 頑張れる
• TRANSACTION AND COMMIT
• 詳細なクエリやオーダー
• マネーがかかること
• 大量のRead/Write
詳細なクエリやオーダー
フレキシブルな検索を
提供するには
100%向いていない
ふと立ち止まる
このアプリに
フレキシブルな
検索機能は
必要だろうか
Remember:
You Ain t
Gonna
Need It
• できぬこと
• JOIN 頑張れる
• TRANSACTION AND COMMIT
• 詳細なクエリやオーダー 向いてない
• マネーがかかること
• 大量のRead/Write
• できぬこと
• JOIN 頑張れる
• TRANSACTION AND COMMIT
• 詳細なクエリやオーダー 向いてない
• マネーがかかること
• 大量のRead/Write
•DynamoDBってなんだ
•できること/できないこと
•もっと使うために
アジェンダ
TRANSACTION
大量のRead/Write
TRANSACTION
トランザクション
コミット
ロールバック
に相当する機能は用意
されていない
ないものはない
ないときつい
銀行口座のお金の振り込み
ゲーム内アイテムの受け渡し
ネットショップ買い物カゴ購入
なくてもいける
銀行口座の入金
ゲーム内アイテムの購入
買い物カゴを使わない単品購入
TRANSACTION
現実的には
アプリケーションレイヤで
ある程度の堅牢さを
保証する必要が出てくる
一連の処理が
どこかで失敗した
場合について考える
のは難しい
処理のリトライの
しやすさを高めることで
"失敗" することを恐れない
ように持っていく
冪等デザインパターン
冪等デザインパターン
何度実行しても
同じ結果になること
(※同じパラメータを渡した場合に)
簡単な例
POST /api/v1/accounts/john/charge
{ 

"request_id": "ABCDEFG",
"charge_amount": 20000
}

user (Hash) request_id (Range) status
user (Hash) amount
john 5000
charge_events
users
POST /api/v1/accounts/john/charge
{ 

"request_id": "ABCDEFG",
"charge_amount": 20000
}

user (Hash) request_id (Range) status
john "ABCDEFG" "Start"
user (Hash) amount
john 5000
charge_events
users
POST /api/v1/accounts/john/charge
{ 

"request_id": "ABCDEFG",
"charge_amount": 20000
}

user (Hash) request_id (Range) status
john "ABCDEFG" "Start"
user (Hash) amount
john 25000
charge_events
users
POST /api/v1/accounts/john/charge
{ 

"request_id": "ABCDEFG",
"charge_amount": 20000
}

user (Hash) request_id (Range) status
john "ABCDEFG" "Finished"
user (Hash) amount
john 25000
charge_events
users
APIを冪等にしておけば
クライアントは
臆せずリトライできる
一連の処理が
どこかで失敗しても
成功するまでリトライして
処理を続行させる
大量のRead/Write
直近50回の
つぶやきを
を表示
50 Read
equals
50読み込みユニット
5.5 米ドル / 月
…?
スレッド形式
の
掲示板
最大
1000レス
1000 Read
equals
1000読み込みユニット
108 米ドル / 月
!?
バッチ処理で
クーポン情報を
2000件挿入
2000 Writes
equals
2000書き込みユニット
1,080 米ドル / 月
!?!?
NO
Burst
Capacity
五分間分の
Capacity Unit
を確保している
Capacity
Unit が余ると
蓄積されていく
10 Read Units
may handle
3000 Read Accesses
in the case of
Burst Capacity
リトライを
しっかり行えば
怖くない
ページング
Scan/Query
と
Limit
Scan/Queryは
読み込み件数ではなく
結果サイズに対して
Capacity Unit 消費
demo※時間があれば
まとめ
TRANSACTION
大量のRead/Write
読み込み Burst Capacity = 1500 / 5min
書き込み Burst Capacity = 300 / 5min
Amazon
DynamoDB
は 1米ドル / 月 でも
それなりに活躍します
Amazon API Gateway
&
AWS Lambda
in 東京
DynamoDB
一択
※SimpleDB もあります
※そのうち Lambda in VPC も
もっとラフに
DynamoDB を
使っていこう!
ご清聴ありがとう
ございました

現場で使えるDynamoDBと冪等デザインパターン