Amazon DynamoDB Accelerator とは
DynamoDB Accelerator (DAX) とインメモリアクセラレーション - Amazon DynamoDB
Amazon DynamoDB はスケールとパフォーマンスのために設計されています。ほとんどの場合、DynamoDB の応答時間は 1 桁台のミリ秒単位で測定できます。ただし、マイクロ秒の応答時間を必要とする一部のユースケースがあります。これらのユースケースでは DynamoDB Accelerator (DAX) が整合性データへのアクセス時に素早い対応を実現します。
DynamoDB のキャッシュ機能です。
機能概要
- DynamoDB と互換性のあるキャッシュサービス
- マイクロ秒単位での応答が可能
- サーバー側の暗号化をサポート
- VPC 環境で動作する
- クラスターは EC2 インスタンスとして VPC 内に起動される
- アプリケーションはクラスターのエンドポイントに接続する
- クロスアカウントアクセスが可能
ユースケース
DynamoDB Accelerator (DAX) とインメモリアクセラレーション - Amazon DynamoDB
- 迅速な読み込み応答時間を必要とするアプリケーション
- リアルタイム入札、ソーシャルゲーム、トレーディングアプリケーションなど
- 少数の項目を他のものよりも頻繁に読み込むアプリケーション
- 人気商品の 1 日限りのセールを行う e コマースシステム
- 読み込み負荷が高いがコストも重要なアプリケーション
- 大規模データセットに対して繰り返し読み込みが必要なアプリケーション
DAX が最適ではないケース
DynamoDB Accelerator (DAX) とインメモリアクセラレーション - Amazon DynamoDB
- 強整合性のある読み込みを必要とするアプリケーション
- 読み込みでマイクロ秒の応答時間を要求しないアプリケーション
- 基礎となるテーブルから繰り返される読み込みアクティビティをオフロードする必要がないアプリケーション
- 書き込み負荷の高いアプリケーション
- 読み込みの繰り返しが少ないアプリケーション
読み込み動作
- 読み込みは GetItem, BatchGetItem, Query, Scan API に対応
- 結果整合性読み込みでは DAX でキャッシュヒットした場合は DAX から応答
- 結果整合性読み込みでは DAX でキャッシュミスした場合は DynamoDB にアクセス
- 強力な整合性のある読み込みでは DAX にキャッシュされない
書き込み動作
- 書き込みは BatchWriteItem, UpdateItem, DeleteItem, PutItem に対応
- 書き込み API の動作は DynamoDB への書き込み後に DAX に書き込まれる書き込みスルー
DAX のコンポーネント
DAX クラスターコンポーネント - Amazon DynamoDB
- ノード: DAX ソフトウェアを実行する 1 インスタンス
- クラスター: ノードの集合
- 1 つはプライマリノード、その他はリードレプリカ
- クラスターエンドポイント: クラスター単位のエンドポイント
- ノードエンドポイント: ノード単位のエンドポイント
- クラスターエンドポイントの利用が推奨されている
試してみた
DAX クラスターを作成して性能を確認してみました。
01. DynamoDB テーブルの作成
以下の設定で作成しました。
- テーブル名: DaxTestTable
- パーティションキー: id (文字列)
上記以外はデフォルト設定です。

02. DAX クラスターの作成
以下の設定で作成しました。
- クラスター名: dax-test-cluster
- ノードファミリー: T 型ファミリー
- ノードタイプ: dax.t2.small
- ノード数: 3
- ネットワークタイプ: IPv4
- サブネットグループ: 新規作成
- サブネットグループ名: dax-test-group
- VPC ID: デフォルト VPC
- サブネット: デフォルトサブネット 3 つ
- セキュリティグループ: デフォルトセキュリティグループ
- AZ の割り当て: 自動
- DynamoDB アクセスのための IAM サービスロール: 新規作成
- IAM ロール名: DAXServiceRole
上記以外はデフォルト設定です。






クラスター作成後にクラスターが利用可能になったことを確認します。

なお、ノードのインスタンスは EC2 コンソールには表示されないインスタンスでした。
03. EC2 インスタンスの作成
以下の設定で DAX にアクセスする EC2 インスタンスを作成しました。
- AMI: Amazon Linux 2023
- キーペア: 不要
- インスタンスコネクトで接続します。
- VPC: デフォルト
- サブネット: デフォルト
- セキュリティグループ: インバウンド、アウトバウンド全開放
- インスタンスプロフィル: AdministratorAccess を付与したプロファイル
EC2 インスタンスの起動後、インスタンスコネクトで接続してアプリケーションを作成します。
endpoint の値は手順 02 で作成したクラスターのエンドポイントに置換してください。
$ sudo dnf update -y
$ sudo dnf install -y nodejs
$ mkdir dax-test
$ cd dax-test
$ npm init -y
$ npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb amazon-dax-client
$ cat <<'EOF' > dax-v3.js
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
DynamoDBDocumentClient,
PutCommand,
GetCommand
} = require("@aws-sdk/lib-dynamodb");
const AmazonDaxClient = require("amazon-dax-client");
const dax = new AmazonDaxClient({
endpoints: [
"your-cluster-endopoint:8111"
]
});
const ddbClient = new DynamoDBClient({
region: "ap-northeast-1",
requestHandler: dax
});
const ddbDocClient = DynamoDBDocumentClient.from(ddbClient);
async function run() {
const tableName = "DaxTestTable";
await ddbDocClient.send(
new PutCommand({
TableName: tableName,
Item: {
id: "1",
message: "Hello from DAX (v3 CommonJS)"
}
})
);
const start = Date.now();
const result = await ddbDocClient.send(
new GetCommand({
TableName: tableName,
Key: { id: "1" }
})
);
const end = Date.now();
console.log("GetItem via DAX:", result.Item);
console.log("Latency via DAX (ms):", end - start);
}
run().catch(console.error);
EOF
04. 動作確認
EC2 インスタンス内でアプリケーションを実行して以下のメッセージ表示されることを確認します。
$ node dax-v3.js
PutItem via DAX (v3 CommonJS) succeeded
GetItem via DAX (v3 CommonJS): { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency via DAX (ms): 21
05. DAX の有無での性能比較
DAX の有無でのレイテンシーを比較するため、DAX を使用しないアプリケーションも作成します。
$ cat <<'EOF' > dynamodb-direct.js
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const {
DynamoDBDocumentClient,
GetCommand
} = require("@aws-sdk/lib-dynamodb");
const ddbClient = new DynamoDBClient({
region: "ap-northeast-1"
});
const ddbDocClient = DynamoDBDocumentClient.from(ddbClient);
async function run() {
const tableName = "DaxTestTable";
const start = Date.now();
const result = await ddbDocClient.send(
new GetCommand({
TableName: tableName,
Key: { id: "1" }
})
);
const end = Date.now();
console.log("DynamoDB Direct GetItem:", result.Item);
console.log("Latency (ms):", end - start);
}
run().catch(console.error);
EOF
アプリケーション作成後、両方のアプリケーションを何度か実行します。
$ node dax-v3.js
GetItem via DAX: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency via DAX (ms): 22
# node dax-v3.js を複数回実行
GetItem via DAX: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency via DAX (ms): 27
GetItem via DAX: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency via DAX (ms): 30
GetItem via DAX: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency via DAX (ms): 21
GetItem via DAX: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency via DAX (ms): 24
$ node dynamodb-direct.js
DynamoDB Direct GetItem: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency (ms): 107
# node dynamodb-direct.js を複数回実行
DynamoDB Direct GetItem: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency (ms): 110
DynamoDB Direct GetItem: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency (ms): 102
DynamoDB Direct GetItem: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency (ms): 106
DynamoDB Direct GetItem: { id: '1', message: 'Hello from DAX (v3 CommonJS)' }
Latency (ms): 106
今回の場合、以下の結果を観測できました。
- DAX 使用時: 2 桁ミリ秒での応答
- DAX 不使用時: 3 桁ミリ秒での応答
以上より、DAX を使用した方がレイテンシーが小さいことを確認できました。
まとめ
今回は Amazon DynamoDB Accelerator について紹介しました。
どなたかの参考になれば幸いです。
Discussion