DynamoDB Accelerator(DAX)を使用してみる
LT
2024年の振り返りをしつつ、2025年に何をしていこうかを記録したいと思います。
2024年の振り返り
2024年は新規プロダクト(広告計測ツール)を開発しながら、フロントエンドに多く触れる機会を得られました。
これまではバックエンドに強いフルスタックエンジニアという立ち位置でしたが、今年はフロント側の技術も学ぶことができ、より広い意味でのフルスタックエンジニアとして成長できたと思っています。
2025年にやっていきたいこと
2025年は、引き続き広告計測ツールの磨き込みを行いながら、さらに新たなプロダクト開発にも挑戦していきます。
技術的には、より高負荷な処理に耐えうるアーキテクチャや、コスト効率の最適化を狙っていきたいと考えています。
DynamoDBを多用しているプロダクトなので、その周辺技術として DynamoDB Accelerator(DAX) を導入し、パフォーマンス改善を図ってみました。
また、プロダクトに活用できる技術を積極的に取り入れていきます。
DynamoDB Accelerator(DAX)とは
さて、本題のDAXについてです。
DAXはDynamoDBの読み取りを数倍から数十倍拡張したキャッシュサービスです。
DAXクラスターがアプリケーションとDynamoDBの間に入り、よく参照されるデータをキャッシュすることで、DynamoDBへのリクエストを減らし、結果的に高速化とコスト削減を同時に実現できます。
ミリ秒からマイクロ秒へと最大 10 倍のパフォーマンス向上を実現します。DAX は、開発者がキャッシュの無効化、データ集計、またはクラスター管理を行う必要なく、DynamoDB テーブルへのインメモリアクセラレーションの追加に必要な作業をすべて担います。DAX は既存の DynamoDB API コールと互換性があるため、アプリケーションロジックを変更する必要はありません。 DynamoDB 同様、プロビジョニングした容量に対してのみのお支払いとなります。スケーリングのパフォーマンスについて心配することなく、顧客向けのアプリケーションの構築に集中できます。(awsの公式からそのまま持ってきました)
プログラムについても、DynamoDBクライアントを置き換えるだけで導入できます。
コストについて
DAXのコスト構造
インスタンスタイプとノードの数、使用時間によって料金が変わります。
下記の例ではインスタンスタイプでdax.r5.large、ノードの数は3です。
DynamoDBのみと比較
DAXのキャッシュがヒットしDynamoDBの読み取り量が減る為、DynamoDBの読み取り料金は減少しますが、DAXのコストが発生するため総合的なコストは増加する傾向にあります。
DAXを使用する
インフラ構築
まず、DAXを構築します。ここではserverless.ymlを用います。
provider:
name: aws
runtime: nodejs18.x
stage: ${opt:stage, 'dev'}
region: ap-northeast-1
vpc:
securityGroupIds:
- sg-xxxxxxxx # 適切なセキュリティグループIDを指定
subnetIds:
- subnet-xxxxxxxx # 適切なサブネットIDを指定
- subnet-yyyyyyyy
resources:
Resources:
DAXSubnetGroup:
Type: AWS::DAX::SubnetGroup
Properties:
Description: Subnet group for DAX cluster
SubnetIds:
- subnet-xxxxxxxx
- subnet-yyyyyyyy
DAXAccessRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: dax.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: DAXAccessPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:GetItem
- dynamodb:Scan
Resource: "*"
DAXCluster:
Type: AWS::DAX::Cluster
Properties:
ClusterName: ${self:service}-${self:provider.stage}-dax
NodeType: dax.r5.large # インスタンスタイプを選択
ReplicationFactor: 3 # DAXノードの数
IamRoleArn: !GetAtt DAXAccessRole.Arn
SubnetGroupName: !Ref DAXSubnetGroup
SecurityGroupIds:
- sg-xxxxxxxx # LambdaなどのサービスとDAX間のトラフィックを許可するセキュリティグループ
SSESpecification:
SSEEnabled: true
アプリケーションの修正
nodejsで実装。
DynamoDBを使用していた場合修正箇所はconst dynamoDB = new AWS.DynamoDB.DocumentClient({ service: dax });
となります。envで初期化せずにdaxで初期化する。
const AWS = require('aws-sdk');
const AmazonDaxClient = require('amazon-dax-client');
// 環境変数からDAXエンドポイントを取得
const daxEndpoint = process.env.DAX_ENDPOINT; // 例: "mydaxcluster.abcdef.clustercfg.dax.ap-northeast-1.amazonaws.com"
// DAXクライアントを初期化
const dax = new AmazonDaxClient({ endpoints: [daxEndpoint], region: 'ap-northeast-1' });
// DAXを使用してDynamoDBドキュメントクライアントを作成
const dynamoDB = new AWS.DynamoDB.DocumentClient({ service: dax });
// 例: DAX経由でDynamoDBをクエリ
const params = {
TableName: 'YourTableName',
KeyConditionExpression: 'analysis_tenant_id = :tenantId and session_id = :sessionId',
ExpressionAttributeValues: {
':tenantId': 'tenant123',
':sessionId': 'session456',
},
};
dynamoDB.query(params, (err, data) => {
if (err) {
console.error('DAXでのクエリ中にエラーが発生しました:', err);
} else {
console.log('クエリに成功しました:', data);
}
});
参照
Discussion