AWS AthenaでS3のログを集計してみた
業務でS3にあるログファイル(JSON行レコード)を集計するタスクをAWS Athenaでやってみたので備忘録。
実はこれ、すでにAWS EMR/Apache Pigで集計しているログファイルなのでPigスクリプトを修正してもよかったんですが実行環境やデプロイが面倒そうだったのと、 Athenaを今覚えたほうが今後の業務で役に立ちそうなのでチャレンジしてみることにしました。 (Pigスクリプトを書いたのは3年前くらいの自分なので頑張れば思い出せるのですが、古い技術を思い出すモチベーションはそんなにない・・・)
そもそもAthenaがSQLで簡単に集計できる、ってのも大きな判断要素ではありました。
というわけでどういう感じで学んでいったかをメモしておきます。
概要を把握
何事もまずは基礎基本から、というわけでまずはAthenaのドキュメントを読んで概要を把握します。
わかったこと
Athena使い方
- テーブル、データベース、を定義する
次にチュートリアルをやってみます。 日本語の解説を見ながら進めたかったのでこの記事を参考にしました。 blog.serverworks.co.jp
これでざっくりと機能と使い方を把握できました。
というわけで今回の対応を進めていきます。 以下、チュートリアルをやったことある人向け。
テーブルの作成
まずはテーブル作成からです。
S3上のログのパスはだいたいこんなかんじ。
s3://bucket_name/path/to/logs/2018/08/01/00/
Athenaにはパーティション機能があり、Hive形式で s3://bucket_name/path/to/logs/year=2018/month=08/date=01/hour=00/
のようになっていればSQLでパーティションを利用できて便利そうだったんですが、今回は単に年月日でディレクトリが切られているだけなので対応しておりません。
こういう場合でも手動でパーティションを作成すれば利用可能なのですが、8月1日のパーティション作成、8月2日のパーティション作成、、、 といった具合にひとつずつパーティションを作成しないといけないようです。
プログラムを作成してJDBCでパーティション作成コマンドを一気に発行・・・とかやればいいみたいですが、 今回はアドホックな集計なのでS3パスの指定を対象の年月日を直接指定しパーティションを利用しないようにしました。
今回は以下のように指定しました。こうすると /2018/08/
以下のすべてのログが集計対象になります。
s3://bucket_name/path/to/logs/2018/08/
ログの形式はJSONを指定します。 JSONだと次ステップのカラム定義の際にで正規表現でログをパースする必要がなくてかなり楽ちんでした。
カラム定義
JSONのプロパティ名をひとつずつカラムとして定義していきます。 JSONパースして一覧を出して選べたりすればかなり楽なのに手動入力なのでつらいです。 しかし、CSVなどの場合は正規表現でパース処理を書かなくてはいけないのでだいぶマシです。
というわけでこれはS3の実際のログを確認しつつ作業します。
ここで、必要ないカラムや値の型が不明なプロパティについては定義しないほうが楽です。 使わないうえによくわからないプロパティをわざわざ定義してパースに失敗するより、定義しないままにしておきましょう。 すべて定義しなくても無視されるだけなので問題ありません。
定義に問題なければプレビューを確認できるので確認しておきましょう。
SQL作成
ここは普通にSQLを書くだけなので特に書くことはありません。
予めS3のログサイズを調べておき実行時間やコストが想定外に膨らまないように注意しましょう。
最初はわざとすくないデーターでテーブルを作っておくといいかもしれません。 (こういう機能がAthenaにあれば簡単なのですが、無さそうです)
結果の確認
AthenaのHisotry、およびS3から確認&ダウンロード可能です。 極力Athena側でクエリに名前をつけて保存しておくと、あとあと再利用などしやすそうです。
所感など
S3のログを手軽にSQLで集計でき、かなり便利でした。 今回はWebコンソールから作業しましたがチュートリアルをやっておけば特に困ることがないぐらい簡単でした。 今後の業務で活用していきたいです。
イマイチなところとしては、SQLをSaveするときDescription入力時にEnterを押すと確定されてしまい、日本語が入力しづらい、というのがありました。。。 これはWebコンソールが日本語化されてないのでいろいろと対応してないところがあるのでしょう・・。まぁそんなに問題ないです。ちょっとつらいだけ。
以上!