パーティションプロジェクションを使うとAthenaのパーティション更新を不要にできる


面倒なAthenaのパーティション更新作業が不要になる、パーティションプロジェクションという機能が静かにそして力強くリリース(2020年5月21日)されました。

今まで

Athenaは新しいパーティションを認識させるための作業が必要で、
定期的にALTER TABLE ADD PARTITIONMSCK REPAIR TABLEを実行したり、Glueクローラーを実行させる必要がありました。

ALTER TABLE ADD PARTITIONMSCK REPAIR TABLEを定期的に実行させるためには、Lambdaを使ったり自前の仕組みを用意する必要があり面倒です。
Glueクローラーは手軽ですが、料金が高いです。(1分しか動かなくても10分の料金が取られるので1時間に1回動かすと、 0.44USD/h * 1/6 * 24 * 31 で クローラー1個に月$54.56かかる)

「パーティション更新のためになんでこんなに苦しまないといけないんだ。Hive形式になっていたら自動で更新してくれてもいいじゃないか」と全Athenaユーザは思っていたと思いますが、やっとパーティション更新から開放されるときが来ました。

パーティションプロジェクションによるパーティション管理の自動化

それでは実際にパーティションプロジェクションを使ってみましょう。
S3には s3://<bucket>/app_log/year=2020/month=6/day=5/hour=1/ のようなHive形式で保存されているものとします。

Hive形式じゃない場合は以下を参照ください
https://docs.aws.amazon.com/athena/latest/ug/partition-projection-kinesis-firehose-example.html

Glueのテーブル編集画面を開く

Glueのテーブル詳細画面にいったら、「テーブルの編集」をクリック。
以下のような画面になります。

テーブルプロパティにパーティションプロジェクションの設定をする

編集画面の下の方に テーブルのプロパティという欄があります。ここにパーティションプロジェクションの設定を入れていきます。

先に設定が完了した画像を見せます。こんな感じです。

まず、 projection.enabledという項目が必要で、trueを入れるとパーティションプロジェクションがONになります。 falseにするとOFFになります。

そして projection.columnName.typeprojection.columnName.range ですが
typeのほうには、enum, integer, date, injected が選択できます。詳しくはこちら。今回はintegerを選択。
rangeにはその値が取りうる範囲を指定します。 下限値,上限値という入力の仕方です。

あとはAthenaから以下のようなパーティションを指定したSQLを実行すればOKです。

SELECT *
FROM "my_db"."app_log"
WHERE year = 2020 AND month = 6 AND day = 5 AND hour = 12
ORDER BY time DESC limit 10;

まとめ

ちょっとした設定が必要ではありますが、パーティション更新作業が不要になったのは大変嬉しいですね。
またパーティション数が多いテーブルではパーティションプロジェクションを使ったほうがクエリ実行が速くなるそうです。

ちなみにこちらのユーザガイドでは日本語でパーティションプロジェクション機能の説明がされてます。
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/athena-ug.pdf