AWS Athena のパーティションプロジェクション
Athena のパーティションプロジェクションを使い、パーティションを Glue Data Catalog へ個別に追加せずにクエリする方法を解説します。
2020 年 6 月に導入された Athena のパーティションプロジェクション を使うと、Glue Data Catalog から個々のパーティションを取得せず、Athena がパーティションの場所を計算します。新しいパーティションを追加するたびに MSCK REPAIR TABLE を実行する必要がありません。
設定
CloudFormation テンプレートの GlueTable.TableInput.Parameters セクション(27〜35 行目)で、以下のプロパティを指定してパーティションプロジェクションを有効にします。
projection.enabled: パーティションプロジェクションを有効にします。projection.year_month.format: パーティションの日付フォーマットを指定します。projection.year_month.range: パーティションの範囲を定義し、オフセット付きのNOW(例:NOW+9HOURS)にも対応します。
projection.year_month.range プロパティは UTC として扱われます。別のタイムゾーンを使いたい場合は、NOW+9HOURS のような形式で時差を明示的に指定する必要があります。
詳細は公式ドキュメントを参照してください。
AWSTemplateFormatVersion: "2010-09-09"Description: Stack for Athena partition projection sampleResources: 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_logsCloudFormation スタックをデプロイします。
aws cloudformation deploy \ --template-file stack.yml \ --stack-name athena-partition-projection-sampleデータのアップロード
続けて、テストデータを S3 バケットにアップロードします。
echo '{"id": 1, "message": "hello"}' > 2021-09.jsonecho '{"id": 2, "message": "world"}' > 2021-10.jsonaws 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 パーティションからデータを取得し、プロジェクションが機能していることを確認します。
SELECT * FROM "sample"."sample_logs"WHERE year_month = '2021/09'LIMIT 10;期待される結果:
1 hello 2021/092021/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-logsaws cloudformation delete-stack --stack-name athena-partition-projection-sampleまとめ
Glue テーブルでパーティションプロジェクションを有効にすると、MSCK REPAIR TABLE を実行せずに、新しくアップロードした year_month パーティションを Athena からクエリできます。
projection.enabled: true と projection.year_month.range: 2021/09,NOW を設定すると、Athena は Glue Data Catalog を参照せず、指定した範囲とフォーマットから有効なパーティションを導出します。新しい月のデータが追加されても、カタログへエントリを登録する必要はありません。
storage.location.template は、実際の S3 キーの構成と一致させる必要があります。また、NOW は UTC で評価されるため、別のタイムゾーンに範囲を合わせる場合は、NOW+9HOURS のようにオフセットを明示してください。
Related posts
Athena と Kinesis Data Firehose で S3 のログをクエリする
Kinesis Data Firehose でログを S3 に配信し、Athena でクエリします。カスタムプレフィックスを使ってパーティションを自動登録する方法を解説します。
Cognito User Pools と OIDC で Slack サインインを実装する
Cognito user pool を OIDC 経由で Slack と連携させ、"Sign in with Slack" を Amplify で Next.js アプリケーションに組み込みます。
Lambda Web Adapter で FastAPI を AWS Lambda にデプロイする
FastAPI で書いた API バックエンドをコンテナ化し、Lambda Web Adapter と AWS CDK を使って単一の Lambda 関数へデプロイします。
API Gateway WebSocket:モック統合の実装
バックエンドの Lambda を使わず、モック統合のみで API Gateway WebSocket API を構築し、あらかじめ用意したレスポンスを返します。
CloudFront 署名付き URL 経由で S3 にアップロードする
CloudFront の署名付き URL を使い、独自ドメイン経由で S3 にアップロードする方法を紹介します。S3 の署名付き URL を直接使えない場合に有用です。
