/var/log/laughingman7743.log

I thought what I'd do was, I'd pretend I was one of those deaf-mutes or should I?

AWS請求レポートをPyArrowでParquet+Snappyに変換する

AWSコストの可視化として、請求レポート*1をAthena*2でクエリを投げられる形式に変換して、Redash*3でダッシュボードを作成していたりします。 元データがCSV+ZIPと非常に扱いにくい形式なのでCSV+GZIPに変換していたのですが、カラムナー形式に変換すると良さそうだなと思い、PyArrow*4を使ってParquet*5+Snappy*6に変換してみました。

以下のスクリプトはS3に出力されている請求レポートをダウンロードしてきて、Parquet+Snappyに変換、Athenaで扱いやすいパス(Hiveのパーティショニング形式)にアップロードするようなPython3のスクリプトの例です。
少し形は違いますが、同じようなことをAirflow*7を使って毎日ぶん回しています。月初にはパーティションを追加、4〜5日目ぐらいまでは前月のデータも更新されるので当月分と合わせて変換するような事をしています。パーティションの追加にはもちろんPyAthena*8を使っています。マルチアカウントで請求情報を集約している場合は ratecostblended_rateblended_costunblended_rateunblended_cost になります。タグも合わせて出力する設定にしている場合は、resource_id の後ろにタグの情報が追加されます。

PyArrowはPandas*9のDataFrameから簡単にParquet形式のデータを出力できます。オンメモリの処理になるので、解凍したファイルのサイズ+αのメモリが必要となります。

Athenaのテーブル定義は以下です。

日付はtimestamp型で持ちたいのですが、文字列型でないとエラーが発生しました。日付型を上手く扱う方法は正直よくわかってないです。。。

カラムナー形式にすることでスキャン量をかなり減らすことができます。クエリの実行速度が速くなることは期待していなかったのですが、意外と速くなりました。CSV+GZIPと比べてクエリにもよりますが、スキャン量は10分の1、速度は5分の1ぐらいになりました。

PyArrow非常に便利ですね。請求レポート以外にもETL処理で色々と使い所はありそうです。
Apache Arrow*10PythonだけでなくRubyもサポートされて始めています*11。素敵なETLライフを。

Enjoy!