【AWS】GlueとLambdaのジョブキューイング機能を比べてみる

## はじめに
はじめまして。
ジールの@r_takaiです。
2024/09/03　AWS より「[AWS Glueでジョブのジョブキューを追加する](https://aws.amazon.com/jp/about-aws/whats-new/2024/09/aws-glue-job-queuing/)」というリリースがありました。

Glueとほぼ同様の機能を持つサービス(※)として、Lambdaがあります。
本記事では、簡単な共通のジョブを用いてGlueおよびLambdaのキューイング機能を検証し、使用感などを比較してみたいと思います。

※AWS Lambdaは「サーバレスのプログラム実行環境（FaaS）」です。
Lambda上でGlueのようなデータ加工や抽出プログラムを実装、実行することが可能です。
Lambdaは実行時間に制限（15分）がある為、比較的小規模（短時間で終了する処理）で使用されることが多く、
一方、Glueの実行時間は48時間である為、比較的規模が大きい（複雑な処理）で使用されます。
他にも、GlueとLambdaには課金方法や実行環境の違い等もあります。

## 1.「ジョブキューイング機能」とは
これまでGlueジョブの同時実行数には制限があり、
Glueジョブが実行されるタイミングで、同時実行数の上限に達していた場合ジョブは実行されない為、時間を空けて実行できなかったジョブを再度実行する必要がありました。

今回「ジョブキューイング機能」が追加されたことにより、
実行できなかったジョブは「キュー」へ移され制限が解除されるまで待ち状態となります。
制限が解除されると、キューの中のジョブが自動的に実行されます。

※Glueジョブのキューイング機能詳細については、下記記事を参考ください。
・[AWSの公式リリース](https://aws.amazon.com/jp/about-aws/whats-new/2024/09/aws-glue-job-queuing/)
・[【アップデート】AWS Clueがジョブキューイング機能を提供開始](https://qiita.com/yakisobapan/items/2015fc17407a6d907ff5)

## 2.GlueとLambdaの設定
キューイングに近い機能（※）があったLambdaとGlueを比較するため、同じ動作環境になるジョブを用意し、設定は以下としました。

※Lambdaでは、関数を[スケーリング](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-concurrency.html)することで同時実行数を制御し、Glueジョブキューイングに類似する動作が可能です。

### 実行ジョブ
S3にファイルが置かれたら、起動し3分待って終了する
<dl><dt>・Glue
<dd>Glue version：Glue 4.0</dd>
<dd>Worker type：G 1X</dd>
<dd>Maximum concurrency：3</dd>
<dd>Job Run Queuing：ON</dd>
<dd>Job timeout (minutes)：4</dd>
<dd>※defaultから変更した設定のみ記載</dd>
<dd>
<details>
<summary>ソース</summary>

```rb
import sys
import time
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
time.sleep(180)
job.commit()
```
</details>
</dd></dt>
<dt>・Lambda</dt>
<dd>タイムアウト：4分</dd>
<dd>同時実行数：3</dd>
<dd>※defaultから変更した設定のみ記載</dd>
<dd>
<details><summary>ソース</summary>

```rb
import json
import time

def lambda_handler(event, context):
    # TODO implement
    time.sleep(180)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```
</details></dd></dl>

## 3.結果を比べてみます
実行状況を「AWSコンソール」から確認しました。

<dl><dt>Glue
<dd>S3へファイルを置くと、Glueジョブが起動しました。
5ファイルをアップしたので、ジョブが2つWaitingになっています。

![Glue monitoring.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/bb88524a-54ce-fb90-6fc4-be41f2984c0e.png)
</dd>
<dd>
3分経過後ジョブが終了したので、Waitingになっていたジョブが起動。

![Glue 1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/588fbd96-9fd0-2ebb-a747-45a11164e9c5.png)
![Glue 2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/7c6ebec1-f87a-2fbb-eba0-c9a0c31890b2.png)

</dd>
<dd>すべてのジョブが終了

![Glue 3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/4e10bdd7-09ee-419c-e9f1-8bece4295847.png)
</dd></dt>
<dt>Lambda
<dd>S3へファイルを置くと、Lambdaが起動しました。Glueと同様に5ファイルをアップしたので、3セット起動されています。

![lambda log.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/42563a74-7bd8-5993-39cd-99474bb7809e.png)
</dd>
<dd>
Lambdaでは、ログからジョブ起動を確認します。
それぞれのログからジョブの起動時間を見ることが出来ます。

![lambda 1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/70ad2918-6d6f-eab4-0c94-cc80ff266331.png)
![lambda 2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/bc1a4d0a-c9d6-e822-ac6c-c1ad430a04fc.png)
![lambda 3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/2129fa78-6330-0ef4-aed8-bf5d11b603f3.png)
</dd>
<dd>
Lambdaダッシュボードからは実行状況が確認できました。

![lambda Metrics.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876783/39119e37-9d90-c020-f36e-e5e46a9e5e4b.png)
</dd>
</dt></dl>

## 4.最後に
結果としてGlueはキューに入っている状況がステータス（Waiting）として確認が出来ましたが、Lambdaはステータス状況を確認できない為、ログやメトリクス「所要時間」等から確認する必要がありました。

今回の検証から、ジョブのキューイング機能については大きな差異は確認できませんでしたが、設定変更のみでGlue単体でジョブの再実行を自動で行うことが出来るようになったことが確認できました。