DynamoDB内のデータをSQLで分析したいと思ったのですが、そうするとETLが必要になります。
四苦八苦しながらデータ分析できるようになるまでの準備を行ったのでメモとして残しておきたいと思います。
DynamoDBのデータをS3に出力する方法
Athenaでデータ分析するためにはS3にデータを保存しておく必要があります。
DynamoDBのテーブルデータをS3に出力するには以下の方法があります。
マネジメントコンソールから手動でDynamoDBテーブルのデータをS3にエクスポートする
マネジメントコンソールを利用するとDynamoDBテーブルのデータをS3にエクスポートできます。
ただし、この方法は手動での作業になるので自動でのS3エクスポートはできません。
AWS CLIを利用してS3にデータをエクスポートする
AWS CLIを利用してエクスポートする方法です。
cronを使えば、定期実行可能ですがサーバが必要になりますね。
EventBridge+Lambda+CDKでS3にエクスポートする
CDKでエクスポートを実行するようLambda関数を準備しEventBridgeで定期的にLambdaを走らせる方法です。
サーバレスで定期的にデータエクスポートができます。
上記の記事に沿ってLambda関数をつくって試してみましたが簡単にエクスポートできました。
ただし、nodejs18ではCDKv3が必要になるのでLambdaは以下のコードで記述しました。
import { DynamoDBClient, ExportTableToPointInTimeCommand } from "@aws-sdk/client-dynamodb"; // ES Modules import
const client = new DynamoDBClient({region:'ap-northeast-1'});
const DynamoDBTableArn = process.env.DYNAMODB_TABLE_ARN;
const ExportS3Bucket = process.env.EXPORT_S3_BUCKET;
const exportInput = {
TableArn: DynamoDBTableArn,
S3Bucket: ExportS3Bucket,
ExportFormat: 'DYNAMODB_JSON',
};
export const handler = async (event) => {
const command = new ExportTableToPointInTimeCommand(exportInput);
const response = await client.send(command);
};
データエクスポートの際に忘れがちな作業
S3にデータエクスポートするためには以下の作業が必要になります。
DynamoDBの対象テーブルに対してPointInTimeRecoveryを設定
S3バケットポリシーとエクスポート実行サービス用のIAMポリシーの用意
エクスポートデータを置くS3バケットに対してバケットポリシーの設定が必要になります。
またCLIやLambdaを使う場合はDynamoDBとS3にアクセスできるようにIAMロールが必要になります。
Glueを使うのがベストプラクティス
上記方法をいろいろと試してみましたが、最終的にAWS Glueを使ってデータ連携することにしました。
AWS Glueについての理解が多少必要になりますが使い慣れるといろいろなことができます。
手順は以下の通りです。
- Glue上でクローラーを作成し、DynamoDBテーブルのスキーマを取り込み、データカタログを生成
- Glue上でETL Jobを作成し、データカタログの情報を利用してDynamoDBのデータをS3に保存
- AthenaにてデータカタログとS3上のデータを利用してテーブルを作成
- クエリを実行してデータを検索
用語を理解するのに最初苦労しました。
スキーマ:データ構造の定義
データカタログ:スキーマ情報の集まりです。"データベース"と"テーブル"の階層構造になっています
クローラー:既存のデータ(DB、ファイルなど)からスキーマ情報を生成するジョブを定義します
ETL Job:データカタログや外部データをもとにETL作業を実施するジョブを定義します
まとめ
いろいろ試行錯誤しましたが最終的には、以下の形でやりたかったことが実現できました。
次はQuickSigntかな。