🤔

Athenaの$pathカラムでの絞り込みはスキャン容量を節約するのか

2022/09/15に公開

この記事の概要

intro

S3のアクセスログに対して、athenaで日付を絞って検索しようとした際
s3://バケット名/prefix/yyyy-mm-dd- 形式でログが吐かれることから
どうもパーティションニングは難しそうという結論になった。
そこで、$pathを用いて絞り込みを行い、容量節約ができないか試してみた。

Amazon Athenaとは

s3上に存在するファイルに対して、SQLクエリで検索ができるサービス
"データのスキャン容量" に対して課金が発生するため
容量の節約には気を配る必要があります。
https://aws.amazon.com/jp/athena/

$path カラムとは

Athenaの隠れカラムで、s3上のファイルパスに該当する。

SELECT "$path" FROM "DB名"."テーブル名"

で取得が可能。詳しくは公式ドキュメント参照
https://aws.amazon.com/jp/premiumsupport/knowledge-center/find-s3-source-file-athena-table-row/

検証準備:DB・テーブル作成

公式のQ&Aにあります。今回はこの手順で作ったもので検証します。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/analyze-logs-athena/

$path での容量節約検証

WHERE = 'パス'の完全一致の場合

SELECT *,"$path" FROM s3_access_logs_db.my_table WHERE "$path" = 's3://my_test_bucket/prefix/2022-09-14-16-43-10-276879D8D6476229'

上記SQLを実行してみたのですが、スキャンが始まらない。
エラーを疑ったものの、一応待ってみると。。。

約11分かかるものの終わりました。
スキャンデータは0.50KBなので、節約できていると言えそうです。

WHERE LIKE 'パス%'の部分一致の場合

SELECT *,"$path" FROM s3_access_logs_db.my_table WHERE "$path" LIKE 's3://my_test_bucket/prefix/2022-09-14-16-43-10-%'

上記SQLを実行すると、理屈の上ではヒットするファイルが1つなので
0.50KB程度で収まるはずが、スキャン容量は数百GBを超えてしまったため
クエリをキャンセルしました。

ORでつなげて一致の場合

SELECT *,"$path" FROM s3_access_logs_db.my_table 
	WHERE "$path" = 's3://my_test_bucket/prefix/2022-09-14-16-43-10-276879D8D6476229'
	OR "$path" = 's3://my_test_bucket/prefix/2022-09-14-00-45-02-F0BA18E8114C6640'
	OR "$path" = 's3://my_test_bucket/prefix/2022-09-14-00-45-05-3027B175B55AE094'

これも容量を節約できているといって良さそうです。

outro

$pathカラム≒ファイル名 が "部分一致しているかどうか" を見た時点で
もうそれはスキャンに該当するみたいです。

先程貼った公式Q&A

ベストプラクティスとして、サーバーのアクセスログバケットに対してライフサイクルポリシーを作成することをお勧めします。ライフサイクルポリシーを設定して、定期的にログファイルを削除します。これにより、各クエリで Athena が分析するデータの量が減ります。

とあるので、S3アクセスログをAthenaで解析する場合
スキャンの容量節約をするには、ライフサイクルポリシーを厳しく設けるか
別のバケットに移してスキャンするなど、ひと手間が必要そうでした。

なにか良い方法知ってる方がいたら、コメントで教えていただけると嬉しいです。

Discussion