SQS を利用して Glue Crawler をイベントに基づいてクロールさせる方法
Glue クローラーは、 SQS を利用したイベント通知で S3 バケットをクロールできます。 これにより、フルスキャンを回避し、クロールのパフォーマンスおよびコストの両方でメリットがあります。
概要
AWS リソース作成
以下の内容で 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
<YOUR_CFN_BUCKET>
を実際の値で置き換え、次のコマンドで CloudFormation スタックをデプロイしてください。
$ 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 Crawler 対象テーブル設定更新
現時点では CloudFormation は Glue Crawler の S3 イベント通知をサポートしていないため、対象のテーブル設定を手動で更新してください。
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
を選択してください。
テスト
JSON Version 1 で Glue テーブルスキーマを更新
以下のコマンドでサンプルの JSON をアップロードして、 S3 イベント通知をトリガーしてください。
$ echo '{"message": "Hello World"}' > sample1.json
$ aws s3 cp sample1.json s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/
Glue クローラーを起動します。
$ aws glue start-crawler --name glue-crawler-test
Glue クローラーのステータスが STOPPING
になるまで確認してください。
$ aws glue get-crawler --name glue-crawler-test | jq -r '.Crawler.State'
STOPPING
Glue テーブルが更新され、新しいスキーマが表示されるはずです。
$ aws glue get-table \
--database-name glue-crawler-test-db \
--name glue-crawler-test-table \
| jq '.Table.StorageDescriptor.Columns'
[
{
"Name": "message",
"Type": "string"
}
]
JSON Version 2 で Glue テーブルスキーマを更新
以下のコマンドでサンプルの JSON をアップロードして、 S3 イベント通知をトリガーしてください。
$ echo '{"message": "Hello World", "statusCode": 200}' > sample2.json
$ aws s3 cp sample2.json s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/
Glue クローラーを起動します。
$ aws glue start-crawler --name glue-crawler-test
Glue クローラーのステータスが STOPPING
になるまで確認してください。
$ aws glue get-crawler --name glue-crawler-test | jq -r '.Crawler.State'
STOPPING
Glue テーブルが更新され、新しい v2 スキーマが表示されるはずです。
$ 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 メッセージ数確認
キュー内のメッセージ数を確認してください。
ApproximateNumberOfMessages: 0
が表示されるはずです。
$ 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"
}
}
クリーンアップ
以下のコマンドを使用して、プロビジョニングされた AWS リソースを削除してください。
$ aws s3 rm s3://glue-crawler-test-<ACCOUNT_ID>-<REGION>/ --recursive
$ aws cloudformation delete-stack --stack-name $STACK_NAME
まとめ
イベント通知で S3 バケットをクロールすることで、フルスキャンを回避でき、クロールのコスト削減とパフォーマンス向上につながります。
この投稿が、お役に立てば幸いです。