DynamoDB

AWS DynamoDBのメモ

前提

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 
},

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