EventBridge Scheduler で MSCK REPAIR TABLE (パーティション更新)を定期実行する
MSCK REPAIR TABLE は Amazon Athena にて実行できるSQL文です。 Hive互換パーティションで定義されたテーブルにて、 パーティションを追加します。パーティションを活用することで、 Athenaクエリのスキャン量を減らせます。 実行時間およびコストにて効果があります。
MSCK REPAIR TABLE はパーティションが追加されるごとに実行する必要があります。
例えば空のバケットから accountid=111111111111/something.log
が追加されたタイミングで、 このログをスキャンするために MSCK REPAIR TABLE 実行が必要です。 さらにその後、 accountid=222222222222/something.log
や accountid=333333333333/something.log
が追加されたタイミングでも同様です。
新規パーティションが追加されるごとに実行するのは手間ですよね。 そこで今回は MSCK REPAIR TABLE を定期実行 する仕組みを作ってみます。
前提
対象となる データカタログ、テーブルは作成済みとします。
今回は以下の ssm_inventory.aws_instanceinformation
を題材とします。
また、クエリ結果を保存するバケットとして aws-athena-query-results-
から始まる S3バケットも作成済みとします。
作っていく
定期実行には EventBridgeスケジューラ を活用します。 この機能についての詳細は以下ブログを参照ください。
以下のような順番で構築します。
- スケジュール用IAMロールを作成する
- スケジュールを作成する
スケジュール用IAMロールを作成する
IAMロール athena-update-partition-schedule-role
を作成します。
信頼ポリシーと許可ポリシーは以下のとおりです
▼ 信頼ポリシー
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "scheduler.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
▼ 許可ポリシー
AmazonAthenaFullAccess AWS管理ポリシーをアタッチします。
⚠注意: より最小権限を目指す場合は、カスタマー管理ポリシー(インラインポリシー)を代わりに記載ください。
スケジュールを作成する
以下のような項目/値で EventBridge スケジュールを作成します。
項目 | 値 |
---|---|
スケジュール名 | athena-update-partition-ssm_inventory-aws_instanceinformation |
スケジュールのパターン | 定期的なスケジュール |
スケジュール | rate(7 days) |
ターゲット | athena:startQueryExecution |
実行ロール | athena-update-partition-schedule-role(= 先ほど作成したロール) |
ペイロード | 後述 |
ペイロードは以下のとおりです。 各種値(主に Catalog, Database, QueryString, OutputLocation) を適宜置き換えてください。
{ "QueryExecutionContext": { "Catalog": "AwsDataCatalog", "Database": "ssm_inventory" }, "QueryString": "MSCK REPAIR TABLE aws_instanceinformation", "ResultConfiguration": { "EncryptionConfiguration": { "EncryptionOption": "SSE_S3" }, "OutputLocation": "s3://aws-athena-query-results-*/schedule/" } }
(参考) Terraform で構築
これまでの構築を Terraform で実施しました。 参考までにリソース部分のコードを以下に記載します。
locals { output_location = "s3://aws-athena-query-results-*/schedule/" database_name = "ssm_inventory" table_name = "aws_instanceinformation" schedule_expression = "rate(7 days)" } # EventBridge Scheduler Role resource "aws_iam_role" "schedule" { name = "athena-update-partition-schedule-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "scheduler.amazonaws.com" } }, ] }) managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonAthenaFullAccess"] } # EventBridge Scheduler resource "aws_scheduler_schedule" "instanceinformation" { name = "athena-update-partition-${local.database_name}-${local.table_name}" schedule_expression = local.schedule_expression flexible_time_window { mode = "OFF" } target { arn = "arn:aws:scheduler:::aws-sdk:athena:startQueryExecution" role_arn = aws_iam_role.schedule.arn input = jsonencode({ QueryString = "MSCK REPAIR TABLE ${local.table_name}" ResultConfiguration = { OutputLocation = local.output_location EncryptionConfiguration = { EncryptionOption = "SSE_S3" } } QueryExecutionContext = { Catalog = "AwsDataCatalog" Database = local.database_name } }) } }
確認する
一時的に 数分おき( rate (2 minutes)
)に実施するように スケジュールを変更しました。
しばらく経つと パーティションが追加されていました。
パーティション追加されたので、Athenaにて問題なく出力できています。
おわりに
以上、MSCK REPAIR TABLE を定期実行してみました。
なお実行頻度には注意ください。 パーティション量やオブジェクト数次第では、 API Call が多くなりコストになる可能性があります。