Amazon DynamoDBテーブルをエクスポートしてAmazon Athenaでクエリしてみた
こんにちは。サービス部の武田です。
Amazon DynamoDBはNoSQLデータベースのため、RDBと異なり柔軟な検索ができません。インデックスが作られていない検索はフルテーブルスキャンとなりリードキャパシティも大量に消費します。
DynamoDBテーブルに対してフルテーブルスキャンが発生するようなクエリを実行したいユースケースがあったのでその手順をまとめました。DynamoDBのエクスポート機能はリードキャパシティを消費しないためこれを利用します。ただしエクスポートにはPITR(ポイントインタイムリカバリ)を有効化しておく必要があります。
今回実施する手順を提示します。
- DynamoDBテーブルをS3へエクスポート(Amazon Ion形式)
- AWS Glue Crawlerを使用してテーブルを作成
- 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は アイオン と発音するようです。これも初めて知りました。