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

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

Glueクローラーは、S3イベント通知に基づいてクロールできるため、フルスキャンを回避でき、クロール性能とコストの両面でメリットがあります。

Takahiro Iwasa
6 min read

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クローラーのターゲットテーブル設定を更新する

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.

テーブルを選択し、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

まとめ

SQSを経由してS3イベント通知をGlueクローラーに接続したところ、2回連続のファイルアップロードによってテーブルスキーマが段階的に更新され、その後SQSキューが空になっていることも確認できました。この空キューの確認こそが、ここでの本当のメリットを示しています。イベントベースのクロールを有効にすると、クローラーは通知のトリガーとなったオブジェクトのみを処理し、バケット全体を再スキャンすることはありません。これが、データセットが増えても実行時間とコストの両方を抑えられる理由です。まだ自動化できない唯一のステップは、コンソール上で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.