パーティションプロジェクションを使った Athena テーブルのパーティション管理の自動化
はじめに
Amazon Athena Partition Projection は 2020 年 6 月に導入され、MSCK REPAIR TABLE
を実行して新しいパーティションを手動で追加する必要がなくなりました。このブログ記事では、Partition Projection を設定し、効果的に使用する方法を解説します。
Partition Projection とは
Partition Projection は Athena がパーティションの値と位置をリポジトリ(例: AWS Glue Data Catalog)から取得する代わりに、設定から計算できるようにする機能です。これにより、大量にパーティション化されたテーブルのクエリ実行時間を短縮できます。
AWS ドキュメントからの主なポイント:
- 効率化: “Partition projection can reduce the runtime of queries against highly partitioned tables.”
- 自動化: “Partition values and locations are calculated from configuration instead of being retrieved manually.”
- オーバーヘッドの削減: “Athena avoids calling
GetPartitions
, leveraging the partition projection configuration instead.”
詳細は AWS 公式ドキュメント をご参照ください。
AWS リソースの設定
以下は Partition Projection を実装するための CloudFormation テンプレートの例です。
AWSTemplateFormatVersion: "2010-09-09"
Description: Stack for Athena partition projection sample
Resources:
S3:
Type: AWS::S3::Bucket
Properties:
BucketName: athena-partition-projection-logs
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
GlueDatabase:
Type: AWS::Glue::Database
Properties:
DatabaseInput:
Name: sample
CatalogId: !Ref AWS::AccountId
GlueTable:
Type: AWS::Glue::Table
Properties:
DatabaseName: !Ref GlueDatabase
CatalogId: !Ref AWS::AccountId
TableInput:
TableType: EXTERNAL_TABLE
Parameters:
classification: json
"projection.enabled": true
"projection.year_month.format": yyyy/MM
"projection.year_month.interval": 1
"projection.year_month.interval.unit": MONTHS
"projection.year_month.range": 2021/09,NOW
"projection.year_month.type": date
"storage.location.template": s3://athena-partition-projection-logs/${year_month}
StorageDescriptor:
Columns:
- Name: id
Type: int
- Name: message
Type: string
Location: !Sub s3://${S3}/
InputFormat: org.apache.hadoop.mapred.TextInputFormat
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed: false
NumberOfBuckets: 0
SerdeInfo:
SerializationLibrary: org.openx.data.jsonserde.JsonSerDe
Parameters:
paths: id,message
StoredAsSubDirectories: false
PartitionKeys:
- Name: year_month
Type: string
Retention: 0
Name: sample_logs
重要ポイント: GlueTable.TableInput.Parameters
設定で重要なのは、GlueTable.TableInput.Parameters
セクション(27–35 行目)です。このセクションは以下のプロパティを使用して Partition Projection を有効にします。
projection.enabled
: Partition Projection を有効にします。projection.year_month.format
: パーティションの日付形式を指定します。projection.year_month.range
: パーティションの範囲を定義します。NOW
とオフセットをサポートしています(例:NOW+9HOURS
)。
projection.year_month.range
プロパティは UTC として扱われます。S3 オブジェクトパスで異なるタイムゾーンを使用する場合は、NOW+9HOURS
のような形式で時間差を指定する必要があります。詳細は 公式ドキュメント をご参照ください。
デプロイ
以下のコマンドで上記の CloudFormation スタックをデプロイします。
aws cloudformation deploy --template-file stack.yml --stack-name athena-partition-projection-sample
セットアップのテスト
データを S3 バケットにアップロードしてテストします。
echo '{"id": 1, "message": "hello"}' > 2021-09.json
echo '{"id": 2, "message": "world"}' > 2021-10.json
aws s3 cp 2021-09.json s3://athena-partition-projection-logs/2021/09/
aws s3 cp 2021-10.json s3://athena-partition-projection-logs/2021/10/
ファイルがアップロードされているか確認します。
aws s3 ls s3://athena-partition-projection-logs/2021/
データのクエリ
2021/09
パーティションからデータを取得するには、以下の SQL クエリを実行します。
SELECT * FROM "sample"."sample_logs"
WHERE year_month = '2021/09'
LIMIT 10;
期待される結果:
1 hello 2021/09
同様に、2021/10
パーティションをクエリします。
SELECT * FROM "sample"."sample_logs"
WHERE year_month = '2021/10'
LIMIT 10;
期待される結果:
2 world 2021/10
クリーンアップ
不要なコストを回避するためにリソースを削除します。
aws s3 rm --recursive s3://athena-partition-projection-logs
aws cloudformation delete-stack --stack-name athena-partition-projection-sample
まとめ
Partition Projection を使用することで、Athena のパーティション管理が簡素化され、時間の節約と複雑さの軽減が可能になります。これにより、開発者はパーティションのメンテナンスを気にすることなく、アプリケーションロジックに集中できます。上記の手順に従うことで、プロジェクトに効率的に Partition Projection を導入できます。
Happy Coding! 🚀