Amazon DynamoDBテーブルをエクスポートしてAmazon Athenaでクエリしてみた

こんにちは。サービス部の武田です。DynamoDBテーブルをS3にエクスポートしてAthenaでクエリするまでの手順をまとめてみました。
2023.01.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービス部の武田です。

Amazon DynamoDBはNoSQLデータベースのため、RDBと異なり柔軟な検索ができません。インデックスが作られていない検索はフルテーブルスキャンとなりリードキャパシティも大量に消費します。

DynamoDBテーブルに対してフルテーブルスキャンが発生するようなクエリを実行したいユースケースがあったのでその手順をまとめました。DynamoDBのエクスポート機能はリードキャパシティを消費しないためこれを利用します。ただしエクスポートにはPITR(ポイントインタイムリカバリ)を有効化しておく必要があります。

今回実施する手順を提示します。

  1. DynamoDBテーブルをS3へエクスポート(Amazon Ion形式)
  2. AWS Glue Crawlerを使用してテーブルを作成
  3. AWS Athenaでクエリ実行

サンプルデータの準備

まず今回使用するテーブルおよびサンプルデータを確認します。SampleOrderTableテーブルは次の属性を持ちます。

  • PK: UserId
  • SK: OrderDate
  • Status

注文のステータス管理をしているテーブルのイメージです。プライマリキーは{UserId, OrderDate}の複合キーとし、UserIdはユーザーID、OrderDateは注文日時です。Statusが現在のステータスを表し、他の属性は省略します。

次のようなデータが格納されています。

UserId OrderDate Status
1 2023-01-01T10:05:05.964000 Completed
1 2023-01-05T06:23:23.625000 Completed
2 2023-01-02T11:56:31.969000 Completed
2 2023-01-14T20:11:40.200000 Canceled
2 2023-01-31T16:40:54.358000 Completed
3 2023-01-20T02:37:38.605000 Completed

このようなテーブルがあったとき、「指定した期間の注文一覧を取得する」というユースケースを考えるとスキャンが必要になります。

やってみた

それではSampleOrderTableテーブルのデータをAthenaでクエリまでやっていきましょう。

まずはエクスポート用のS3バケットを作成します。今回はsample-order-table-exportバケットを作成しました。

次に、作成したバケットにテーブルのエクスポートをしていきます。テーブルページのアクションから「S3へのエクスポート」を選択します。

「送信先S3バケット」に事前に作成したsample-order-table-exportバケットを指定。

「エクスポートされたファイル形式」にはAmazon Ionを選択します。指定したら「エクスポート」ボタンをクリックしましょう。

約6分ほどでエクスポートされました。dataフォルダーにgz形式で格納されています。

ちなみに内容(の一部)は次のようになっていました。

$ion_1_0 {Item:{UserId:"2",OrderDate:"2023-01-02T11:56:31.969000",Status:"Completed"}}
$ion_1_0 {Item:{UserId:"2",OrderDate:"2023-01-14T20:11:40.200000",Status:"Canceled"}}
$ion_1_0 {Item:{UserId:"2",OrderDate:"2023-01-31T16:40:54.358000",Status:"Completed"}}

続いてエクスポートされたデータのGlueテーブルを作成します。手動で定義することも可能ですが、今回はGlue Crawlerを使用します。Glueのページにアクセスし、「Create crawler」をクリックします。

crawler名はexport-sample-order-tableとします。

データソースの設定をします。「Add a data source」をクリックします。

「Data source」をS3とし、「S3 path」はエクスポートされたs3://sample-order-table-export/AWSDynamoDB/01675138425581-ba6bd04a/dataを指定します(途中の値は環境によって変わります)。

Glueが使用するIAMロールを作成します。既存のロールを使用してもよいですが、今回はAWSGlueServiceRole-export-sample-order-tableロールを作成しました。

出力先の設定です。「Target database」はdefaultとし、「Table name prefix」はsample_order_tableとしました。

以上の設定でCrawlerが作成されました。「Run crawler」ボタンをクリックすることで、オンデマンドでCrawlerが走ります。

無事にテーブルが作成されました。

それではAthenaでクエリしてみましょう。まずはプレビューで表示すると次のような結果が返ってきます。

「指定した期間の注文一覧」を取得するために例として次のクエリを実行してみます。

SELECT item.userid,
	item.orderdate,
	item.status
FROM "default"."sample_order_tabledata"
WHERE date_parse(item.orderdate, '%Y-%m-%dT%H:%i:%s.%f') BETWEEN date '2023-01-10' AND timestamp '2023-01-28' - interval '0.001' second
ORDER BY item.orderdate;

結果は次のようになりました。

いい感じに取得できていますね!

まとめ

DynamoDBのエクスポート機能は使用したことがなかったためいい経験になりました。ちなみにAmazon Ionは アイオン と発音するようです。これも初めて知りました。