AWS GlueでS3に保存したTSVをJSONに変えちゃう！


# AWS Glue
https://aws.amazon.com/jp/glue/details/

マネージドETLサービス。
データソース（S3/RDBMS）をクロールし、ETL処理を実行して指定の場所にアウトプットしてくれる

現状(2017/11 現在)は東京リージョンでは使用できない。
ソースとなるS3データが東京リージョンでも問題ない。ただし、Glueが吐き出すデータは対応リージョンである必要がある。

# 試してみる
時系列でプレフィックスを切っているS3ファイルにTSVファイルが格納されていく環境を想定して、Glueを適応してみる。

```bash:S3のディレクトリ構成
s3://S3_BUCKET/DATA_LABEL/yyyy/mm/dd/HH/
```

この下にTSVファイルが格納されるとする。

### step1 クローラーの定義
Glueで一番最初にやるのがこのクローラーの設定です。

![スクリーンショット 2017-11-27 21.39.21.png](https://qiita-image-store.s3.amazonaws.com/0/52141/b0e2a7ba-f4c8-212b-36a6-6b10afd1ba0c.png "スクリーンショット 2017-11-27 21.39.21.png")

左のペインから `Crawlers` を選択して `Add crawler` から新規でクローラーを定義します。

- Crawler name: クローラー一覧の画面に表示されるクローラーの名前
- Data store: クローラーが何処を見に行くかを指定
	- S3: 対象にS3を指定 (__S3を選択した場合のみ記載します__)
	- JDBC: 対象にDBを選択
- Crawl data in: クローラーが見に行くのは自分のアカウントか別のアカウントかを選択
	- Specified path in my account: defaultで選択されてます。
- Include path: データのある場所までのS3のパスを指定 `s3://BUCKET_NAME/FOLDER_1/FOLDER_2/` で指定する
	- 注意: ここはデータの発生する場所なので、東京リージョンのバケットを指定して大丈夫です(__直書きしないと何かエラー出るかもしれません__)
- Add another data store: 今回は単一なので `No`
- Choose an IAM role: ここで最低でも `S3` に対して、`CloudWatch` に対して `Glue` に対して等必要十分な権限を持ったロールを指定して下さい。
- Create a schedule for this crawler
	- Frequency: 起動するタイミングを指定します。今回は手動実行のみでテストするので `Run on demand` を選択します
- Configure the crawler's output: クローラーが収集したメタデータの保持についての設定
	- Database: データ構造であるテーブルを格納するための単位。DB設計時の `Databases` の指定と同じノリで構わないと思われる。
		- まだ空のはずなので `Add database` で作成する
		- optionalはdefaultのまま


##### ここまで終わるとクローラーが作成される

![スクリーンショット 2017-11-27 21.56.25.png](https://qiita-image-store.s3.amazonaws.com/0/52141/b81e46fe-1c29-727a-809c-a8ab2be8b2f4.png "スクリーンショット 2017-11-27 21.56.25.png")

作成したクローラーにチェックを付けて `Action` から実行することでメタデータの収集をしてくれる
実行時間は対象のデータ量が多ければ多いほどかかります。最初数十GB単位で喰わせたら１時間たっても終わらなかったので少しの量でテストしました。

##### 終了すると、 `Databases-Tables` の下に定義が出来上がります。
##### これが出来上がったらようやくETL処理について書いていきます

### JOB
`ETL-Jobs` から新規作成をします。

- Name: jobの名前です
- IAM role: 必要十分な権限を持ったロールを選択して下さい
- A proposed script generated by AWS Glue: Mapping構造を定義したPythonスクリプトを生成してくれるのでこれを選択。
- Script file name: 保存時にスクリプトファイルに付ける名前
- S3 path where the script is stored: スクリプトファイルの格納先
	- `s3://BUCKET_NAME/FOLDER_1/FOLDER_2/` で指定する
	- 必ずGlueの対応リージョンである必要がある
- Temporary directory: JOB実行中に使用するtmp領域の指定
	- `s3://BUCKET_NAME/FOLDER_1/FOLDER_2/` で指定する
	- 必ずGlueの対応リージョンである必要がある
- Advanced properties
	- Job bookmark: どのデータまで処理したかをGlue側で見ていてくれる（重複実行しない）
		- Enableとしました。（新しいデータのみ処理したいので）
- Choose your data sources: 先程作成したデータソースを選択します
- Choose your data targets: 処理したデータの出力先についての設定（新規作成を選択する)
	- Data store: S3
	- Format: いくつかフォーマットがありますが今回はTSVをJSONに変換するので `JSON` を選択
	- Compression type: gzip (出力データの圧縮形式)
	- Target path: データを何処に格納するか
		- `s3://BUCKET_NAME/FOLDER_1/FOLDER_2/` で指定する
		- 必ずGlueの対応リージョンである必要がある
- Map the source columns to target columns.
	- ここでデータの変更について簡単に記載できる。columnを減らしたり、型を指定したり、順番変えたりできる。

##### 作成したら作成したJOBにチェックを付けて `Action-Run job`から実行できる
これもデータソースの量によって実行時間が大きく変わってくるので検証時は少量のデータで検証すると良い

![AWS_Glue_Console_と_AWS_Glueを使いたいので試してみる.jpg](https://qiita-image-store.s3.amazonaws.com/0/52141/1ef6fc91-ad1c-d97f-abc1-afe1ccffc865.jpeg "AWS_Glue_Console_と_AWS_Glueを使いたいので試してみる.jpg")

終わるとこんな感じで `Successded` って表示になる

Choose your data targetsで指定したS3ディレクトリを見に行くとJSONデータが作成されている。

![S3_Management_Console.jpg](https://qiita-image-store.s3.amazonaws.com/0/52141/5da5e6c7-f0d5-cb68-88ff-3c6a75da295a.jpeg "S3_Management_Console.jpg")


# Job bookmar

S3データを時系列順にソートしてSSを撮りましたが、`part-t-00000/part-t-00001` が２個あるのが見えると思います。
これは、初回実行した後、データソースにデータを追加してもう一度実行したため追加のデータが格納されたためです。

この際、 __クローラーを動かしてからでないと、新規データがないと判断しJOBが実行されない__ ことに注意しましょう。

##### SSのとおり、タイムスタンプと先頭の文字列が違うだけで同一のフォルダに吐き出される点に注意が必要

今回は出力されたPythonスクリプトを何もいじらずにデータ形式だけ変更しましたが、書けばいろいろ出来るようなのでガンガン使っていきたい。

# トリガーの設定
トリガーを設定することでJOBを任意のタイミングで実行させることが出来ます。
クローラーを１０分毎に、JOBを１時間毎に実行とかにしておけば何もせずとも動きます。
上記のブックマークをONにしておけば差分のみ出力されるので処理済みデータのローテート等も問題なく可能です。



# 参考
[AWS Glue 実践入門：サービスメニュー内で展開されている「ガイド付きチュートリアル」を試してみた| Developers.IO](https://dev.classmethod.jp/cloud/aws/aws-glue-tutorial/)