LoginSignup
2
2

More than 5 years have passed since last update.

DynamoDBに一定ペースで更新処理をしてたのにWCUを超えてしまった

Posted at

uuidをキーとするテーブルの各レコード(DynamoDB 的には厳密にはアイテム)に対して、各行にuuidリストが書かれたテキストファイルを読んで対象のレコードにフラグをセットしていくスクリプトを実行した。
本記事末尾に記載したような Node.js のスクリプトで 80WCU (Write Capacity Unit) 消費で済むと思っていた。しかし結果的に 240WCU と3倍消費していた。

原因

  • RCU/WCU の U は Unit であり、Item (Record) ではない。RCU の Unit は 4KB であり、WCU の Unit は 1KB であった。
  • テーブルに入ってる既存のデータが各レコードで平均 3KB 近くあったため、1更新に 3WCU 使っていた。

反省と考察

  • レコードの 4KB を最大値の基準として気にしていたが、RCU と WCU の Unit に差があったことを知らなかった。
  • テーブル設計が最適ではなかった。
    テープルの中で更新頻度が高く読み取り頻度が低いフィールド(属性)があり、かつ独立できるものがあった。これはテーブルを分けるべきだった。
  • 1レコードのサイズを太らせていくような実装は危険、不要になったフィールドは消し込んだ方が良い(もちろんその場合もWCUを考慮した削除が必要である)。

スクリプト

'use strict';

const fs = require('fs');
const AWS = require('aws-sdk');
const LineStream = require('byline').LineStream;
const PacedWorkStream = require('paced-work-stream');
const PromisedLife = require('promised-lifestream');

const docClient = new AWS.DynamoDB.DocumentClient({ region 'ap-northeast-1' });
const TABLE_NAME = 'users';

const pacedWorker = new PacedWorkStream({
    concurrency: 8,
    workMS: 100, // 1000ms/sec / 100ms * 8 = 80 WCU
  }, function(line) {
    const uuid = line.toString();
    console.log('%s Begin %s', new Date().toISOString(), uuid);

    return docClient.update({
        TableName: TABLE_NAME,
        Key: { uuid: uuid },
        UpdateExpression: 'set #a = :v',
        ExpressionAttributeNames: { '#a': 'newFlag' },
        ExpressionAttributeValues: { ':v': true }
      })
      .promise()
      .then(() => {
        pacedWorker.countTag('update');
        console.log('%s End uuid:%s', new Date().toISOString(), uuid);
      })
      .catch(err => {
        console.warn(new Date().toISOString(), err);
      });
  });

PromisedLife([
  fs.createReadStream('uuid.txt'),
  new LineStream(),
  pacedWorker
])
.then(() => {
  console.log(pacedWorker.tagCounts);
})
.catch(err => {
  console.error(err);
});
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2