AWS AthenaでBigデータ解析

## WHY Athena

複数社のASPで吐き出されたフォーマットばらばらの膨大なcsvデータ達を結合しまくってデータ解析せなあかん時ってありますよね

- いちいちDBサーバー作ってインポートしてらんない
- いちいちフォーマット合わせてらんない
- ExcelでVLOOKUPとか処理重すぎてクライアント動かない

そこでAthena

![Analytics_AmazonAthena.png](https://qiita-image-store.s3.amazonaws.com/0/38126/b7522596-9fdb-5896-f5db-5a93ecb3d95a.png "Analytics_AmazonAthena.png")

## WHAT Athena

- サーバーレスで環境構築不要
- S3にファイルを上げてAthenaのコンソール画面でSQL叩くだけで結果出力
- Prestoベースなので重たいクエリの結果が早い
- 出力されたデータはcsvでDL可能
- S3の標準の金額とAthenaのクエリ従量なので安い（クエリのスキャン 1 TB あたり 5 USD）

いいことだらけ

## Saving Point

### リージョン

実行タイミングが毎日何百回とかでなければS3のリージョンは 米国東部 (バージニア北部) か 米国西部 (オレゴン) がオススメ

Athenaはどのリージョンでも金額は変わらない

![スクリーンショット_2017-12-12_14_48_47.jpg](https://qiita-image-store.s3.amazonaws.com/0/38126/ceecc3ad-cc2a-b7dd-9c47-b1cf91b28caf.jpeg "スクリーンショット_2017-12-12_14_48_47.jpg")

### データ圧縮

本データがGZIP圧縮されてればその分スキャンデータが少なくなるので安くなる

### 列のチューニング

元データに不要な列はなるべく消すこと、消せば消した分だけスキャンデータが少なくなるので安くなる

列指向データ形式（Apache Parquet や Apache ORC）に形式を変換すれば不要な列を読まなくなるのでこれも安くなる

列の削除はExcelやエディタでの編集も良いが、AWS Glueを使うと良い

> AWS Glue
> 
> Athenaの作業がもっと楽になるやつ
> S3の本データをの変換が素早く出来る＋Athena用のデータ形式に変換してくれる
> 他社都合で勝手にデータの列形式とか変わっちゃった時にお役立ち
> 東京リージョンデビューはもう少しかかる模様なので 米国東部 (バージニア北部) か 米国西部 (オレゴン) で
> 
> 詳しい使い方は[クラスメソッドさんのところ](https://dev.classmethod.jp/cloud/aws/sugano-037-glue-for-athena/)で

### パーティション

テーブル作成時にパーティション設定することで、クエリの条件に日付関連の方法を入れると、勝手に条件外のデータを読まなくなります

日毎とか週毎、月毎などに分類されるデータはパーティション設定するといいでしょう

パーティションにするにはS3に上げる時にディレクトリを **dt=ほにゃらら** にしてCREATE文に PARTITIONED BY って書けばいいです

こんな感じ

<img src="https://qiita-image-store.s3.amazonaws.com/0/38126/ad509be6-51eb-ca7a-5689-d91f422f7b9f.png">


```sql:yakiniku.osushi.sql
CREATE EXTERNAL TABLE IF NOT EXISTS yakiniku.osushi (
  `name` string,
  `media_name` string,
  `media_type` string,
  `device` string,
  `carrier` string,
  `click_date` timestamp,
  `regist_date` timestamp,
  `user_id` string,
  `session_id` string 
) PARTITIONED BY (
  dt string 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://yakiniku-tabetai/osushi-tabetai/';
```

パーティション用のディレクトリを新たに作った場合は、テーブルに認識する必要があるので、Load partitionsしましょう

![スクリーンショット_2017-12-12_14_28_15.jpg](https://qiita-image-store.s3.amazonaws.com/0/38126/10426983-68f3-ac59-110e-556dd5e9e17d.jpeg "スクリーンショット_2017-12-12_14_28_15.jpg")

## Trouble Shooting

### クエリは262144バイト以内

クエリが長すぎだとこんな風に怒られます、修正しましょう

> Your query has the following error(s):
> 
> Your query has exceeded the maximum query length of 262144 bytes. Please reduce the length of your query and try again. If you continue to see this issue after reducing your query length, contact customer support for further assistance. (Service: AmazonAthena; Status Code: 400; Error Code: InvalidRequestException; Request ID: 1effab6b-df02-11e7-820b-c99df83a2b03)


### 稀にクエリが通らない

最近は頻度は減りましたが、並行で重たいクエリを投げてると稀にエラーになります

サーバレスアーキテクチャ上Lambdaみたいなもんだと思っているので、負荷によるエラーはないと思っているのですが、そういうときは時間を追いて再度実行するとクエリが通ります

### S3 SELECTでいいんじゃね？

S3 SELECTはAWS re:Invent 2017で発表されたサービスで、S3にあるデータファイルを直接SELECT分で出力できるみたいです

今はプレビュー版ですが、AWSから許可してもらったので試した所、**group by、order by 使えない**等の制約があったため使っていません

あとCLI慣れてないと他にも躓くところがあるかもです

ただ、今後今回のようなケース（他社ASPからデータDLして分析）はS3 SELECTで十分になるかもしれません

あくまでAthenaはCLI苦手な人用となるのかも



**おわり**