イベント駆動型の AWS Glue クローラー:SQS ベースのトリガーを設定する

イベント駆動型の AWS Glue クローラー:SQS ベースのトリガーを設定する

S3 イベント通知と SQS を使い、バケット全体を繰り返しスキャンせずに AWS Glue クローラーを差分実行します。

Takahiro Iwasa
6 min read

AWS Glue クローラーは、S3 イベント通知 を使って、新規または変更されたオブジェクトだけを処理できます。実行のたびにバケット全体をスキャンする必要がないため、クロール時間とコストを抑えられます。

構築

以下の CloudFormation テンプレートで、キュー、バケット、クローラーを構築します。

AWSTemplateFormatVersion: '2010-09-09'
Description: Glue crawler test
Resources:
SqsQueue:
Type: AWS::SQS::Queue
Properties:
SqsManagedSseEnabled: true
QueueName: glue-crawler-test-queue
SqsQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
Queues:
- !Ref SqsQueue
PolicyDocument:
Version: '2008-10-17'
Id: __default_policy_ID
Statement:
- Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
- !GetAtt IAMRoleGlueCrawler.Arn
Action: sqs:*
Resource: !GetAtt SqsQueue.Arn
- Effect: Allow
Principal:
Service: s3.amazonaws.com
Action: sqs:*
Resource: !GetAtt SqsQueue.Arn
S3Bucket:
Type: AWS::S3::Bucket
DependsOn: SqsQueuePolicy
Properties:
BucketName: !Sub glue-crawler-test-${AWS::AccountId}-${AWS::Region}
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
NotificationConfiguration:
QueueConfigurations:
- Event: 's3:ObjectCreated:*'
Queue: !GetAtt SqsQueue.Arn
PublicAccessBlockConfiguration:
BlockPublicAcls: TRUE
BlockPublicPolicy: TRUE
IgnorePublicAcls: TRUE
RestrictPublicBuckets: TRUE
IAMRoleGlueCrawler:
Type: AWS::IAM::Role
Properties:
Path: /service-role/
RoleName: !Sub glue-crawler-test-service-role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: glue.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: cw-logs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- PolicyName: glue
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- glue:CreateTable
- glue:GetDatabase
- glue:GetTable
- glue:UpdateTable
Resource: "*"
- PolicyName: s3
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:ListBucket
- s3:PutObject
Resource: '*'
GlueDatabase:
Type: AWS::Glue::Database
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseInput:
Name: glue-crawler-test-db
GlueTable:
Type: AWS::Glue::Table
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseName: !Ref GlueDatabase
TableInput:
Name: glue-crawler-test-table
TableType: EXTERNAL_TABLE
Parameters:
classification: json
StorageDescriptor:
Location: !Sub 's3://${S3Bucket}/'
Compressed: false
InputFormat: org.apache.hadoop.mapred.TextInputFormat
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
SerdeInfo:
SerializationLibrary: org.openx.data.jsonserde.JsonSerDe
GlueCrawler:
Type: AWS::Glue::Crawler
Properties:
Name: glue-crawler-test
Role: !Sub service-role/${IAMRoleGlueCrawler}
Targets:
CatalogTargets:
- DatabaseName: !Ref GlueDatabase
Tables:
- !Ref GlueTable
SchemaChangePolicy:
UpdateBehavior: UPDATE_IN_DATABASE
DeleteBehavior: LOG

スタックをデプロイします。

Terminal window
STACK_NAME=glue-crawler-test
aws cloudformation package \
--template-file template.yaml \
--s3-bucket <YOUR_CFN_BUCKET> \
--s3-prefix "$STACK_NAME/$(date +%Y)/$(date +%m)/$(date +%d)/$(date +%H)/$(date +%M)" \
--output-template-file package.template
aws cloudformation deploy \
--stack-name $STACK_NAME \
--template-file package.template \
--capabilities CAPABILITY_NAMED_IAM

Glue クローラーのターゲット設定を更新する

2023 年 1 月時点では、CloudFormation から Glue クローラーの S3 イベント通知を設定できません。クローラーのターゲットを手動で更新します。

https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/947

CloudFormation Support For S3 Event isn’t currently available. S3 Event Crawler’s integration with CloudFormation is in scope and in the works. We plan on releasing this coverage to Cloudformation some later this year. Thank you for patience.

S3 ターゲットを選択し、Edit をクリックします。

Subsequent crawler runs セクションで Crawl based on events を選択します。

テスト

バージョン 1 のアップロード

サンプルの JSON ファイルをアップロードし、S3 イベント通知を発生させます。

Terminal window
echo '{"message": "Hello World"}' > sample1.json
aws s3 cp sample1.json s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/

Glue クローラーを起動します。

Terminal window
aws glue start-crawler --name glue-crawler-test

ステータスが STOPPING になるまで監視します。

Terminal window
$ aws glue get-crawler --name glue-crawler-test | jq -r '.Crawler.State'
STOPPING

更新された Glue テーブルのスキーマを確認します。

Terminal window
aws glue get-table \
--database-name glue-crawler-test-db \
--name glue-crawler-test-table \
| jq '.Table.StorageDescriptor.Columns'

期待される出力。

[
{
"Name": "message",
"Type": "string"
}
]

バージョン 2 のアップロード

新しいバージョンの JSON ファイルで同じ手順を繰り返します。

Terminal window
echo '{"message": "Hello World", "statusCode": 200}' > sample2.json
aws s3 cp sample2.json s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/

Glue クローラーを起動します。

Terminal window
aws glue start-crawler --name glue-crawler-test

ステータスが STOPPING になるまで監視します。

Terminal window
$ aws glue get-crawler --name glue-crawler-test | jq -r '.Crawler.State'
STOPPING

更新された Glue テーブルのスキーマを確認します。

Terminal window
aws glue get-table \
--database-name glue-crawler-test-db \
--name glue-crawler-test-table \
| jq '.Table.StorageDescriptor.Columns'

期待される出力。

[
{
"Name": "message",
"Type": "string"
},
{
"Name": "statuscode",
"Type": "int"
}
]

SQS メッセージ数の確認

SQS キューにメッセージが残っていないことを確認します。

Terminal window
queue_url=$(aws sqs get-queue-url --queue-name glue-crawler-test-queue | jq -r '.QueueUrl')
aws sqs get-queue-attributes \
--queue-url $queue_url \
--attribute-names ApproximateNumberOfMessages
{
"Attributes": {
"ApproximateNumberOfMessages": "0"
}
}

クリーンアップ

この例でプロビジョニングしたリソースを以下のコマンドで削除します。

Terminal window
aws s3 rm s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/ --recursive
aws cloudformation delete-stack --stack-name $STACK_NAME

まとめ

S3 イベント通知を SQS 経由で Glue クローラーへ渡すと、連続してアップロードしたファイルからテーブルスキーマを段階的に更新できます。SQS キューが空になったことで、クローラーが通知を処理したことも確認できます。

イベントベースのクロールでは、クローラーは通知で参照されたオブジェクトだけを処理し、バケット全体を再スキャンしません。データセットが増えても、実行時間とコストを抑えられます。

2023 年 1 月時点では、Subsequent crawler runsCrawl based on events に切り替える操作にコンソールが必要です。CloudFormation で構成を一元管理したい場合は、リンク先の GitHub issue を確認してください。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.