旅行しながら働く ムラサメ研究所社長ブログ

主にゲームやプログラミングのログ

AWS Dynamoのメモ

前提

Dynamo初めて触る人向けのDynamoのまとめ
多分これだけ知ってればDynamoチョトデキル

About

DynamoはNoSQLにジャンルされる KVSである。当然RDBより速い
機能的には、Redisより少し出来る事が多く、MongoDBより少ない
速度的には Redisに劣るので、必要に応じてAPI CacheでRedisを建てる
従量課金なので常時起動するコストがない

メリット

フルマネージドなので、設定もデプロイも不要でオートスケーリングする
死活監視も不要なので、夜もゆっくり寝ることができる

テーブル仕様

Indexが2個しか指定できない(後述GlobalSecondaryIndexで追加は可能だが制限がある)
Indexは PartitionKey(PK)のみか、PartititionKey+SortKey(SK) のどちらかを設定する必要がある
Index以外のフィールドは自由(レコード毎にフィールドが違っても問題ない)
PK(PK+SK)で一意性が保たれる必要がある(Indexが同じレコードはエラー)

フィールド(アトリビュート

基本的には数字か文字列
日付は文字列なりUNIX Timeにして・・
バイナリも入る(未使用)
それらの配列も入れることができる Booleanもある
Mal、List、Nullもあるが未使用

クエリー

PKは =判定しか出来ない(完全一致オンリー) Indexはテーブル作成時に設定し、以降変更することが出来ない
IndexにSKを含めて作成した場合でも PKのみのクエリが可能
SKでクエリーする場合はかならず PKと併用する必要がある(SK単体のクエリは不可能)
SKは =、<、<=、>、>=、Betweer、BeginWith(前方一致) が出来る SK指定時はソートすることが可能

スキャン

全件取ってくるので遅いのでなるべく使わない
Indexでクエリかけられない場合は後述のGSIも検討すべき

フィルタ

クエリやスキャンの後、条件でレコードを除外することが出来る
Indexに指定していないフィールドでも条件一致させられる
でもクエリ後なので、ヒット件数が多い場合は遅い

Update、Insert

Dynamoではアップサートである(同じIndexの項目があればUpdate、なければインサート) Update時はフィールドの即値指定以外に計算式が入るため f = f+5 のようなアトミック計算も可能
またUpdate時に update if f == 5 のような条件指定も可能
アトミックカウンタも存在するので、トランザクションが無くてもそれなりの事ができる

GlobalSecondaryIndex(GSI)

Indexとは別に 検索用のIndexを作成することが出来る
Indexと同じく PKあるいはPK+SK で作成することが出来る
クエリもIndexと同じ
内部実装は同じテーブルをレプリケーションしているため、GSIを増やすとデータ容量増えるので注意
投影フィールド(レプリケーションするフィールド)を指定できるので必要なものだけにすること
Indexと違い キーの一意性は必要ない(PK+SKが同じレコードも作成可能)

バッチオペレーション

ReadやInsert、Delete等をまとめることができる
Dynamoの料金体系は基本的に Read/Write単位で課金されるため(もちろんデータ量もあるが)バッチ処理出来る時はしたほうがお得
ただし Updateはバッチ処理できません!

トリガー

Dynamoでレコードの変更があったさい Lambda関数を呼ぶことが可能
ただし、1秒間に4回ポーリングして変更があったさい起動するようなので、重いかもしれない

トランザクション

ない。楽観的なトランザクション
が、Updateの条件式などを使えば ロックフリー的なことは可能 dynamodb-transactions というのが簡易トランザクション機能を提供する

バックアップ

通常S3等に退避させることが多いと思う
特定リージョンでは オンデマンドバックアップが可能
テーブルやレコードを削除しても、バックアップから復元することが可能(未使用のため詳細不明)

グローバルテーブル

他のリージョンとも自動的にレプリケーションされるテーブルを作成することが可能

DocumentClient(ライブラリ)

AWS.DynamoDB.DocumentClient を使うとほんの少し楽になる
具体的には、素でDynamoDBライブラリを使うと すべてのフィールドにたいして "N" や "S" といった型情報が必要だが、それを省略可能

"Key": {
  "PK": {"S":"pk"},
  "SK": {"N":1} 
},

"Key": {
  "PK":"pk",
  "SK": 1 
},

と出来る。地味にありがたい