DynamoDBへの大量データ投入
-
Pythonではやったことがあったけど、Node.jsではやっていないかったのでやってみると、高速だった。 1putごとにawaitしないから高速ですね。
-
https://dev.classmethod.jp/articles/nodejs-dynamodb-scan-stream/ クラスメソッドさんの記事まんまできる
- 「スクリプトで50万件のテストデータを作成」の箇所のtsをjsに変える
-
DynaomoDBテーブルは、オンデマンドキャパシティを使う
-
Pythonの並列処理を作成するのは苦手だけど、Node.jsならばPromise.all() で非同期処理で同時に実行できCPUパワーを十分に使える
AWS Lambdaの設定
- Lambdaをメモリ1024MB、タイムアウト1分にする
- Lambda Layer使うのですが割愛します
DynamoDB
- テーブル名 :sugimoto-scan
- パーティションキー :id,文字列
- ソートキー:指定なし
- 設定をカスタマイズ にて、キャパシティーモードで「オンデマンド」を選択
実行ロール
- 追加するポリシー(東京リージョンにDynamoDBテーブルがある想定)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:Put*",
"dynamodb:Update*",
"dynamodb:BatchWriteItem",
"dynamodb:Scan"
],
"Resource": [
"arn:aws:dynamodb:ap-northeast-1:*:table/sugimoto-*",
]
}
]
}
ソース
const { DynamoDB } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocument } = require("@aws-sdk/lib-dynamodb");
const { v4 } =require("uuid");
const ddb = new DynamoDB({
region: 'ap-northeast-1',
})
const ddbDoc = DynamoDBDocument.from(ddb)
async function main() {
for (let i = 0; i < 10; i++) {
await Promise.all(
Array.from({ length: 100 }).map(async () =>
ddbDoc.put({
TableName: 'sugimoto-scan',
Item: {
id: v4(),
name: "ABCDEFGHあああああ-~いいいいいえええええええ1234567890",
},
})
)
)
}
}
exports.handler = async (event) => {
await main();
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
実行時間
- コールドスタートで2500ms, ウォームスタート1400msで終わるので、forループ回数は10倍も余裕
- Lambdaの実行時間を15分まで延ばせば さらに増やすことが可能
注意点
- オンデマンドキャパシティなので書込み料金がまあまあかかる
- プロビジョンドだと、エラーになります(キャパシティを使い切ってしまう)
- プロビジョニングモードでは、書込み量が上限に引っかかってしまいエラーになる