AWS Glue Studio の Example jobs を実行してみる

## はじめに

AWS のサーバーレスデータ統合サービス **AWS Glue** を使ってみました

その中でも分かりやすそうな **AWS Glue Studio** で Example jobs を実行します

具体的には以下のようなことをします

- S3 上の CSV ファイル3つを結合する
- 特定の列だけ抽出する
- 各列を数値や論理型に変換する
- Parquet 形式で出力する
- 出力ファイルに対して Athena から SQL を実行する

![etl.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/ec1c6684-01de-0a4e-c4a2-3e0ed9a8c27c.png)

Parquet はデータを効率的に保存・検索するためのファイル形式です

https://www.databricks.com/jp/glossary/what-is-parquet

思ったよりすんなり行かなかったので記事に残しておきます

## AWS Glue とは

データの ETL = Extract Transfer Load = 収集、変換、読込の一連処理を簡単に実装します

https://aws.amazon.com/jp/glue/

サーバーレスなので、インフラのことを気にする必要がありません

データのスキーマ（項目、型）も Glue が自動的に認識してくれます

## AWS Glue Studio とは

AWS Glue の ETL をブラウザ上の GUI で組めます

https://docs.aws.amazon.com/ja_jp/glue/latest/dg/edit-nodes-chapter.html

## IAM ロールの作成

ジョブを実行する IAM ロールを作成します

IAM ロールのページで「ロールを作成」をクリック

![スクリーンショット 2024-05-28 16.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b7e3dc83-27ad-3db4-9394-0114a647a65c.png)

「信頼されたエンティティタイプ」に「AWS のサービス」を選択（デフォルト）
「ユースケース」に「Glue」を選択
「次へ」をクリック

![スクリーンショット 2024-05-28 15.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/35ebd0cb-9da5-e04d-68d6-edc9c1c9042b.png)

許可ポリシーに以下のポリシーを選択し、「次へ」をクリック

- AWSGlueServiceRole
- AmazonS3FullAccess

:::note info
今回は S3 バケット上の CSV ファイルを入力、 Parquet ファイルを出力とするため、 S3 へのアクセス権限を与えます

また、とりあえず FullAccess にしていますが、本来は必要最低限の権限にする必要があります
:::

「ロールを作成」をクリック

![スクリーンショット 2024-05-28 16.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/01e2fe0e-f77c-9e9a-32b9-58bc26c27cde.png)

## S3 バケットの作成

出力先となる S3 バケットを作成します
すでにあるバケットを利用する場合は不要です

:::note info
入力元は公開されているバケットを使用します
:::

## データベースの作成

AWS Glue では、扱うデータのメタデータ（構造の定義情報など）をデータカタログという機能で管理します
データカタログの機能の中で、メタデータの保存先となるのがデータベースです
ジョブを実行する前にデータベースを作成しておく必要があります

AWS Glue のページでサイドメニューから Data Catalog |> Databases を開きます
「Add database」をクリックします

![スクリーンショット 2024-05-28 16.30.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/bad64e9f-d2a8-44e4-2b6f-1b4b5523871f.png)

「Name」に適当な名前を入力し、「Create database」をクリックします

![スクリーンショット 2024-05-28 16.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c41ef6c4-9019-8af9-dce1-ef0464ee9c7d.png)

## ジョブの作成

AWS Glue のページでサイドメニューから ETL jobs |> Visual ETL をクリックします
AWS Glue Studio のページが開きます
Exsample jobs を開き、中の「Visual ETL job to join multiple sources」を選択して「Create example job」をクリックします

![スクリーンショット 2024-05-28 16.49.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6ae9fa0d-900f-ff59-aa93-82f6f328f288.png)

ジョブ定義の GUI が開きます

![スクリーンショット 2024-05-28 16.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/bc545149-04f9-3aa4-9c75-c5545ab81aba.png)

## ジョブの設定

「Job details」のタブをクリックします
「Name」を適当な名前に変更します
「IAM Role」に作成しておいた IAM ロールを選択します
右上「Save」をクリックします

![スクリーンショット 2024-05-28 19.24.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/52cb4c09-a37c-4b3b-a93c-b42697dbdaee.png)

うまく行くと、「Run」ボタンが活性化して押せるようになります
でも、まだ押さないでください

![スクリーンショット 2024-05-28 19.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/038bb9ce-f854-cc56-4c58-96195b35442b.png)

## 出力先の指定

「Visual」のタブに戻ります
一番下にある「Catalog」のノードをクリックします
「S3 Target Location」に作成した S3 バケットを入力します

![スクリーンショット 2024-05-28 19.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d9bc48ca-1ea0-6772-b11b-e39dda6f84a5.png)

下の方にある「Database」で作成したデータベースを選択します

![スクリーンショット 2024-05-28 19.36.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e709c33a-f125-bd59-1af5-58cc731ba0e3.png)

右上「Save」をクリックして保存しておきます

## ジョブの確認

### Data source

左上の「Plan assignment」をクリックすると、入力ファイルの設定が確認できます
下の「Data preview」でデータの内容（先頭２００件）が確認できます
「S3 URL」の下、「View」ボタンをクリックするとS3上のファイルが確認できます

![スクリーンショット 2024-05-28 19.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b3e3edc6-4a33-30f3-9623-d64f6d3275de.png)

他の各入力ファイル（Data source）のCSVファイルは以下のような内容です

Plan assignment
![スクリーンショット 2024-05-28 19.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/683eb1ad-1863-96e4-4f6c-9a9b2a8b99da.png)

Subscribers
![スクリーンショット 2024-05-28 19.52.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/3915099f-e0ec-6ee2-ef54-42f034b8006d.png)

Plans
![スクリーンショット 2024-05-28 19.53.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/147455e6-41b3-a31e-4f5f-02079b62aae6.png)

各 Data source のノードで「Output schema」を見ると、ジョブの実行前の時点で各列の定義ができていることが分かります

![スクリーンショット 2024-05-28 20.00.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d9a7136a-073a-9382-f296-48558175cf65.png)

ちなみに、 S3 上のファイル以外に Kinesis や データベースなども入力にすることができます

![スクリーンショット 2024-05-28 21.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/f98d86ed-2ae8-9784-6de8-7e83f8442e7a.png)

### Transform - Join

Join のノードを開くと、２つの入力ファイルを結合する定義を確認できます

:::note warn
ただし、「Data preview」は各入力ファイルの先頭200行同士を結合しているため、キーの一致するレコードが存在せず、空になってしまいます（仕様上の問題）
しかも、この状態になると、もう一段下の Join ノードで「plan_id」が選択できなくなっています
「Save」しないようにしましょう
:::

![スクリーンショット 2024-05-28 19.57.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/60c3c618-3b93-4610-bcaa-28fe6be538e9.png)

### Transform - SelectFields

「Select Fields」のノードをクリックすると、列の選択（いわゆる射影、SELECT句）定義が確認できます
ここまでで結合した入力ファイルから、指定した列だけを抜き出します

![スクリーンショット 2024-05-28 20.15.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b84a7421-fbf8-f4e8-3256-8e62f1c23ee1.png)

### Transform - ChangeSchema

「Change Schema」のノードをクリックすると、各列の型変換定義が確認できます
ここまでは全列「string」でしたが、ここで「bigint」や「boolean」に変換されます

![スクリーンショット 2024-05-28 20.21.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e9f5b2a5-c11d-b463-5487-b334ae2e4a49.png)

ちなみに、 Transform では他にも SQL による操作や欠損血処理などが可能です

![スクリーンショット 2024-05-28 21.13.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/bd4911da-81cd-7886-1924-6583921c1f0c.png)

### Data target

改めて「Catalog」ノードを開くと、「Format」に「Parquet」を指定しており、 Parquet 形式に変換していることが分かります

![スクリーンショット 2024-05-28 19.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d9bc48ca-1ea0-6772-b11b-e39dda6f84a5.png)

Target としては各種データベースも指定可能です

![スクリーンショット 2024-05-28 21.14.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/ba76d360-8238-291b-0cc0-2ed6fae0bf61.png)

## スクリプトの確認

「Script」タブを開くと、 GUI で繋いだノードをスクリプトとして確認できます

![スクリーンショット 2024-05-28 21.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6f62d331-21d1-e42f-9e31-cdae87db87b6.png)

## ジョブの実行

いよいよ右上「Run」をクリックしてジョブを実行しましょう
ジョブの実行状況は「Runs」タブで確認できます

![スクリーンショット 2024-05-28 20.30.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/a87649e8-1062-ca73-4472-f4edaccbac58.png)

1分強で「Succeeded」になります

![スクリーンショット 2024-05-28 20.33.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/9de7ca74-b031-a48e-2500-e28e6b0e0790.png)

左メニュー Data Catalog |> Databases |> Tables をクリックします
テーブルの一覧に subscriber_plans テーブルが作成されています

![スクリーンショット 2024-05-28 21.00.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/3a6c76e6-300d-ef89-c846-b9618441e2eb.png)

テーブル名をクリックするとテーブル詳細が確認できます

![スクリーンショット 2024-05-28 20.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/40082927-2788-7457-f6ec-3ce08f21d4ce.png)

出力先の S3 バケットを確認すると Parquet ファイルが作成されています

![スクリーンショット 2024-05-28 20.48.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c4641fb5-7cea-a937-d5c3-95c673e2ada6.png)

## Athena からのデータ分析

Athena のページを開き、「クエリエディタを起動」をクリックします

![スクリーンショット 2024-05-28 20.38.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/f25cf15a-4556-4a51-cc39-d15c9c841678.png)

「設定」タブを開き、「管理」ボタンをクリックします

![スクリーンショット 2024-05-28 20.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/7dce37e4-2fc1-cc57-f545-9edc4590b9a2.png)

「Location of query result」　に S3 バケットを指定します

![スクリーンショット 2024-05-28 20.53.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/3c5cd4d7-1a31-e59b-b79c-f3cc95d52868.png)

データベースを指定すると、 Glue で作ったテーブルに対して SQL が実行できました

![スクリーンショット 2024-05-28 20.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/2ea62412-99b9-1e17-5809-5d3522dccd59.png)

## まとめ

AWS Glue を使うことで ETL ジョブが作れました

日次や月次のデータ変換バッチ処理を組むのには便利そう