Glue コンソールから Spark UI で処理が分散できているか見てみる

# はじめに
そろそろ2023年も終わりますね。今年も様々なAWSサービスのアップデートがあったと思います。皆さんは何が印象に残っているでしょうか。
私が印象に残ったアップデートの一つに、「GlueのコンソールからSpark UIが見れるようになった」ことがあります。

https://aws.amazon.com/jp/about-aws/whats-new/2023/11/aws-glue-serverless-spark-ui-observability-metrics/

これが出るまでは、CloudFormationは公式から提供されてはいますが、自分自身でEC2上にSpark UIのサーバーを建てる必要がありました。

# Spark UI とは
Spark UIは、Glue ETLジョブの内部で実行されている処理を可視化してくれるツールです。
Sparkは、大規模データを処理するために分散して処理を行います。その分散具合やそれぞれの処理時間などが見れるようになるため、パフォーマンスチューニングに利用されます。

https://spark.apache.org/docs/latest/web-ui.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/fbff4cb2-5041-90de-229e-3c817691cd01.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/bf849b34-c00c-f163-43fb-d5d6f7acd619.png)

# 今回試すこと
まずは、ワーカー数を2にしてGlue ETLジョブを実行します。
その実行内容をSpark UIで確認し、ワーカー数をどのように増やせば効率的に処理が出来るかを考えたいと思います。

Glueのワーカー数というのは、分散の度合いのようなものです。
以下の図が分かりやすいですが、ワーカータイプがG.1Xであれば、1つのワーカーにつき1DPU、1Executorです。Executorというのが処理するマシンに相当するため、ワーカー数が10なら10個のマシンで並列処理するイメージです。
ただ、10個のうち1つはDriverという全体の指示係のようなものを担うので、実際に処理を行うのは残りの9個ということになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/29d24f4f-a2fc-1b65-4631-41f360713edc.png)
https://d1.awsstatic.com/webinars/jp/pdf/services/202108_Blackbelt_glue_etl_performance2.pdf より

# ワーカー数2の場合
では、まずはワーカー数2（G.1Xでの最低ワーカー数）で実行してみます。

## 処理の内容
処理はかなり簡単なもので、S3上のcsvデータをロードして、parquetファイルで出力するだけです。
入力のcsvファイルは、1つのcsvファイルで2.2GBです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/c891042c-e3ac-189b-0f3f-042029addc2a.png)

このジョブを実行すると、3分17秒で処理が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/19eb2c02-29bd-b92c-f90c-78f80b7a5c14.png)

## 結果をSpark UIで見てみる
まずはジョブの結果から View detailsをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/a707cc99-c0e8-204a-d4b1-cd49dbb39457.png)

下の方にあるSpark UIをクリックするとみることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/9ca32a32-4cb6-9ae2-98c9-0f21a95cb303.png)

以下がSpark UIの画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/4b3c0bf2-4b34-9791-bd51-36846c65433a.png)

さらに、Descriptionを2回クリックしていくと、詳細が見れます。
下の表を見ると、**Taskが36個**実行されていることが分かります。Sparkでは、処理をTaskという単位まで分解して、それぞれのExecutor上で実行していきます。上の図では緑の帯が36個あり、1つのExecutorで36個のTaskを実行しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/309c5089-09d3-2809-f23c-b8a20a94c789.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/9049b8a6-69af-b3fe-8b29-acd37c77a82f.png)

## どうすれば効率よく処理が分散する？
ワーカー数が2つだと、36個のTaskを1つのExecutorで実行していました。これを、複数のExecutorで分散処理することを考えます。いくつのExecutorで分散させればよいでしょうか？

まずは1つのExecutorでいくつのTaskが処理できるかを考えると、今回の場合（Glueのバージョン4.0、ワーカータイプG.1X）は4個になります。これは、Executorあたりのコアの数が以下のように4つと指定されているためです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/f7331f09-3008-d21e-7d33-1507c02d31e3.png)

つまり、今回の場合は36個のTaskがあるので、36÷4=9個のExecutorを準備出来れば、一番効率よく処理できることになります。ワーカー数で言うと、10を指定すれば良いですね（1つはDriverとなるため）。

:::note info
[Glueのドキュメント](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html#:~:text=%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%2D%2Dexecutor%2Dcores,-%E4%B8%A6%E5%88%97%E3%81%AB%E5%AE%9F%E8%A1%8C)によると、ジョブパラメーターの`--executor-cores`で指定できるようです。8を指定して実行すると、`spark.executor.cores`も8となりました。
:::


# ワーカー数を変更してやってみる
ワーカー数10で実行した場合、このように1分20秒と先ほどの3分17秒よりも実行時間が短縮されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/70e88224-9ebe-4428-1503-a414d339db7b.png)

肝心のSpark UIを見てみると、以下のように9個のExexutorできれいに並列処理されていますね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/1b4c50fe-4db2-3d70-c9ac-ff22b8ae0aa9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/e56ea5aa-9d0d-084e-c51f-9f089d4c7c1e.png)

# まとめ
- Sparkのパフォーマンスチューニングに便利なSpark UIが、Glueのコンソールから簡単に見れるようになった。
- Executor上でTaskがうまく並列処理できていないようなら、ワーカー数を増やすのが良い。
- ワーカー数をいくつに増やせばよいかは、Task数によって考える。

これ以外にもSparkのパフォーマンスチューニングには色々な種類があるので、Spark UIを色々と見ながら試してみてはいかがでしょうか。

# 参考

https://d1.awsstatic.com/webinars/jp/pdf/services/202108_Blackbelt_glue_etl_performance1.pdf

https://d1.awsstatic.com/webinars/jp/pdf/services/202108_Blackbelt_glue_etl_performance2.pdf

https://repost.aws/ja/knowledge-center/glue-container-yarn-memory-limit

https://qiita.com/uryyyyyyy/items/ba2dceb709f8701715f7#job-stage-task