概要
DynamoDBを使用していて複数データを保存、削除する際、BatchWriteItem
を使用することになる。
具体的な使用例と注意点をまとめる。
BatchWriteItem
データの保存、削除等をまとめて実行できる。
並列で処理されるため、パフォーマンスは上がる。
※レイテンシは低減されるが、消費キャパシティは変わらないのでコストが下がるわけではない。
基本的なルール
AWSのdocumentにはこのような記載がある。
BatchWriteItem - Amazon DynamoDB
The BatchWriteItem operation puts or deletes multiple items in one or more tables. A single call to BatchWriteItem can write up to 16 MB of data, which can comprise as many as 25 put or delete requests. Individual items to be written can be as large as 400 KB.
ポイントとしては、
- 最大25項目までまとめて登録できる
- 一度に送信できる最大のデータ量は16MB
- 項目一つに対しての最大のデータ量は400KB
Laravelを使用している場合
Laravelを使用するのであれば、GitHub - baopham/laravel-dynamodb: Eloquent syntax for DynamoDBを利用するとEloquentモデルでDynamoDBにアクセスできるようになる。
具体例
Putの例
以下のようにDynamoDb::marshalItem()
に挿入したい値を連想配列で渡し、それをsetItem
に渡す。
(marshalItem
とはAWS-SDKのMarshaler
クラスに書かれている、DynamoDBのitem形式のフォーマットでJSON形式のテキストとPHPのArray型の変換ができるようになるメソッド)
$query = DynamoDb::table($table)
->setItem(DynamoDb::marshalItem($item->toArray()))
->prepare()
->query;
$putRequests[] = ['putRequest' => $query];
その後、以下のような形でbatchWriteItem
を使う。
DynamoDb::newQuery()->setRequestItems([
$table => $putRequests,
])
->prepare()
->batchWriteItem();
※この例はPutのケース、作成する項目が25件までなので注意が必要(25件以上の場合、ValidationErrorになる)
chunkする際に気をつける点
また、以下のような方法でchunkをする場合は注意が必要。
100件のUserを保存するケース。
$userPutRequestsChunk = $users->map(function ($user) use ($table) {
return [
'PutRequest' => DynamoDb::table($table)
->setItem(DynamoDb::marshalItem($user->toArray()))
->prepare()
->query
];
})
->chunk(25)
->all();
foreach ($userPutRequestsChunk as $requests) {
DynamoDb::newQuery()->setRequestItems([
$table => array_values($requests->all()),
])
->prepare()
->batchWriteItem();
}
foreachの1ループ目は問題無いが、それ以降$requestのkeyが 25, 50, 75から始まるため、SerializationException
が返され1ループ目のデータしか保存されない。
そのため、keyが0から始まっていない場合はarray_values()
等でkeyを振り直す必要がある。
SerializationException
の際は基本的にformatエラーのため、何が入っているか確認が必要。
必ずResponseを確認するべき
batchWriteItem成功時、全Requestが成功したとは限らないのが罠。
もしRequestが失敗した場合、Response内のUnprocessedItems
に失敗したデータが入るので、この中身が空になるまで再度処理をする必要がある。
まとめ
最後のResponseを確認しないといけない箇所は、DynamoDBを使用する上で必ず知っておくべきことだと感じた。