EventBridge Scheduler で MSCK REPAIR TABLE (パーティション更新)を定期実行する

2024.05.14

MSCK REPAIR TABLE は Amazon Athena にて実行できるSQL文です。 Hive互換パーティションで定義されたテーブルにて、 パーティションを追加します。パーティションを活用することで、 Athenaクエリのスキャン量を減らせます。 実行時間およびコストにて効果があります。

MSCK REPAIR TABLE はパーティションが追加されるごとに実行する必要があります。

例えば空のバケットから accountid=111111111111/something.log が追加されたタイミングで、 このログをスキャンするために MSCK REPAIR TABLE 実行が必要です。 さらにその後、 accountid=222222222222/something.logaccountid=333333333333/something.log が追加されたタイミングでも同様です。

新規パーティションが追加されるごとに実行するのは手間ですよね。 そこで今回は MSCK REPAIR TABLE を定期実行 する仕組みを作ってみます。

前提

対象となる データカタログ、テーブルは作成済みとします。

今回は以下の ssm_inventory.aws_instanceinformation を題材とします。

img

また、クエリ結果を保存するバケットとして aws-athena-query-results- から始まる S3バケットも作成済みとします。

img

作っていく

定期実行には EventBridgeスケジューラ を活用します。 この機能についての詳細は以下ブログを参照ください。

以下のような順番で構築します。

  1. スケジュール用IAMロールを作成する
  2. スケジュールを作成する

スケジュール用IAMロールを作成する

IAMロール athena-update-partition-schedule-role を作成します。

img

信頼ポリシーと許可ポリシーは以下のとおりです

▼ 信頼ポリシー

{
  "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(= 先ほど作成したロール)
ペイロード 後述

img

img

ペイロードは以下のとおりです。 各種値(主に 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) )に実施するように スケジュールを変更しました。

しばらく経つと パーティションが追加されていました。

img

パーティション追加されたので、Athenaにて問題なく出力できています。

img

おわりに

以上、MSCK REPAIR TABLE を定期実行してみました。

なお実行頻度には注意ください。 パーティション量やオブジェクト数次第では、 API Call が多くなりコストになる可能性があります。

参考