DynamoDB ストレージ
DynamoDB ストレージ実装は、ElectroDB を用いたシングルテーブル設計パターンを活用し、Mastra 向けにスケーラブルで高性能な NoSQL データベースソリューションを提供します。
機能
- Mastra のあらゆるストレージ要件に対応する効率的な単一テーブル設計
- 型安全な DynamoDB アクセスのための ElectroDB ベース
- AWS の認証情報、リージョン、エンドポイントをサポート
- 開発用途で AWS DynamoDB Local と互換
- Thread、Message、Trace、Eval、Workflow のデータを保存
- サーバーレス環境向けに最適化
インストール
npm install @mastra/dynamodb@latest
# または
pnpm add @mastra/dynamodb@latest
# または
yarn add @mastra/dynamodb@latest
前提条件
このパッケージを使用する前に、プライマリキーおよびグローバルセカンダリインデックス(GSI)を含む所定の構造を持つ DynamoDB テーブルを作成しておく必要があります。このアダプタは、DynamoDB テーブルとその GSI が外部でプロビジョニング済みであることを前提としています。
AWS CloudFormation または AWS CDK を用いたテーブルのセットアップ手順の詳細は、TABLE_SETUP.md に記載されています。先に進む前に、必ずその手順どおりにテーブルが構成されていることを確認してください。
使い方
基本的な使い方
import { Memory } from "@mastra/memory";
import { DynamoDBStore } from "@mastra/dynamodb";
// DynamoDB ストレージを初期化
const storage = new DynamoDBStore({
name: "dynamodb", // このストレージインスタンスの名前
config: {
tableName: "mastra-single-table", // 使用する DynamoDB テーブル名
region: "us-east-1", // 任意: AWS リージョン。既定は 'us-east-1'
// endpoint: "http://localhost:8000", // 任意: ローカルの DynamoDB 用
// credentials: { accessKeyId: "YOUR_ACCESS_KEY", secretAccessKey: "YOUR_SECRET_KEY" } // 任意
},
});
// 例: DynamoDB ストレージで Memory を初期化
const memory = new Memory({
storage,
options: {
lastMessages: 10,
},
});
DynamoDB Local を使ったローカル開発
ローカル開発には、DynamoDB Local を利用できます。
-
DynamoDB Local を起動する(例: Docker 使用):
docker run -p 8000:8000 amazon/dynamodb-local
-
DynamoDBStore
をローカルのエンドポイントに向けて設定する:import { DynamoDBStore } from "@mastra/dynamodb"; const storage = new DynamoDBStore({ name: "dynamodb-local", config: { tableName: "mastra-single-table", // ローカルの DynamoDB にこのテーブルが作成されていることを確認してください region: "localhost", // ローカルでは任意の文字列で可。一般的には 'localhost' endpoint: "http://localhost:8000", // DynamoDB Local では、特別な設定をしない限り通常は認証情報は不要です。 // ローカル認証情報を設定している場合: // credentials: { accessKeyId: "fakeMyKeyId", secretAccessKey: "fakeSecretAccessKey" } }, });
ローカルの DynamoDB インスタンスでも、テーブルと GSI は作成する必要があります。たとえば、ローカルのエンドポイントを指定した AWS CLI を使用してください。
パラメーター
name:
config.tableName:
config.region?:
config.endpoint?:
config.credentials?:
AWS IAM の権限
コードを実行する IAM ロールまたはユーザーには、指定した DynamoDB テーブルおよびそのインデックスとやり取りするための適切な権限が必要です。以下はサンプルポリシーです。${YOUR_TABLE_NAME}
は実際のテーブル名に、${YOUR_AWS_REGION}
および ${YOUR_AWS_ACCOUNT_ID}
は適切な値に置き換えてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem"
],
"Resource": [
"arn:aws:dynamodb:${YOUR_AWS_REGION}:${YOUR_AWS_ACCOUNT_ID}:table/${YOUR_TABLE_NAME}",
"arn:aws:dynamodb:${YOUR_AWS_REGION}:${YOUR_AWS_ACCOUNT_ID}:table/${YOUR_TABLE_NAME}/index/*"
]
}
]
}
重要な考慮事項
アーキテクチャの詳細に入る前に、DynamoDB ストレージアダプターを使用する際は次の要点を念頭に置いてください。
- 外部テーブルのプロビジョニング: このアダプターを使用する前に、DynamoDB テーブルとその Global Secondary Indexes(GSI)を自分で作成・設定しておくことが_必須_です。TABLE_SETUP.md のガイドに従ってください。
- シングルテーブル設計: すべての Mastra データ(スレッド、メッセージなど)は1つの DynamoDB テーブルに保存されます。これは DynamoDB に最適化された意図的な設計判断であり、リレーショナルデータベースの手法とは異なります。
- GSI の理解:
TABLE_SETUP.md
に記載の GSI の構成を理解していることは、データ取得や想定されるクエリパターンを把握するうえで重要です。 - ElectroDB: アダプターは DynamoDB とのやり取りを管理するために ElectroDB を使用しており、生の DynamoDB 操作に対する抽象化と型安全性のレイヤーを提供します。
アーキテクチャのアプローチ
このストレージアダプターは、DynamoDB で一般的かつ推奨される ElectroDB を活用したシングルテーブル設計パターンを採用しています。これは、各エンティティ(スレッド、メッセージなど)ごとに専用の複数テーブルを用いるのが通例のリレーショナルデータベース用アダプター(@mastra/pg
や @mastra/libsql
など)とはアーキテクチャが異なります。
このアプローチの主なポイント:
- DynamoDB ネイティブ: シングルテーブル設計は DynamoDB のキー・バリューおよびクエリ機能に最適化されており、リレーショナルモデルを模倣する場合と比べて、しばしば性能やスケーラビリティに優れます。
- 外部でのテーブル管理: コードからテーブル作成用のヘルパー機能を提供するアダプターとは異なり、このアダプターはDynamoDB のテーブルと関連する Global Secondary Index (GSI) が、使用前に外部でプロビジョニング済みであることを前提とします。AWS CloudFormation や CDK などのツールを用いた詳細な手順については TABLE_SETUP.md を参照してください。本アダプターは既存のテーブル構造との対話にのみ専念します。
- インターフェースによる一貫性: 基盤となるストレージモデルは異なっても、このアダプターは他のアダプターと同様に
MastraStorage
インターフェースに準拠しており、Mastra のMemory
コンポーネント内で相互に置き換えて使用できます。
単一テーブルにおける Mastra データ
単一の DynamoDB テーブル内では、Threads、Messages、Traces、Evals、Workflows といったさまざまな Mastra のデータエンティティが、ElectroDB によって管理・識別されています。ElectroDB は各エンティティタイプに対し、固有のキー構造や属性を備えたモデルを定義します。これにより、同一テーブル内で多様なデータ型を効率よく格納・取得できます。
たとえば、Thread
アイテムは THREAD#<threadId>
といったパーティションキーを持ち、同じスレッドに属する Message
アイテムはパーティションキーに THREAD#<threadId>
、ソートキーに MESSAGE#<messageId>
を用いる場合があります。TABLE_SETUP.md
に記載の Global Secondary Indexes (GSI) は、スレッド内のすべてのメッセージの取得や、特定のワークフローに関連するトレースのクエリといった、これら異なるエンティティをまたぐ一般的なアクセスパターンを支えるよう戦略的に設計されています。
単一テーブル設計の利点
この実装は ElectroDB を用いた単一テーブル設計パターンを採用しており、DynamoDB において次の利点があります。
- 低コスト(見込み): テーブル数を減らすことで、特にオンデマンドキャパシティ使用時に、Read/Write Capacity Unit(RCU/WCU)のプロビジョニングや管理を簡素化できます。
- 高パフォーマンス: 関連データを同一の場所にまとめたり、GSI により効率的にアクセスできるため、一般的なアクセスパターンで高速なルックアップが可能です。
- 運用の簡素化: 監視・バックアップ・管理対象のテーブルが少なくなります。
- アクセスパターンの複雑さの低減: ElectroDB により、単一テーブル上のアイテムタイプやアクセスパターンの複雑さを管理しやすくなります。
- トランザクション対応: 必要に応じて、同一テーブル内に保存された異なる「エンティティ」タイプ間で DynamoDB のトランザクションを利用できます。