背景
Step Functionsで「StartJobRun.sync」を用いてGlueJobの実行をする場合、
ジョブの完了からStep Functions側でその完了を確認するまで、最大5分ほどかかる場合があります。(AWSサポートで確認済み:2022/7/23)
今回は「StartJobRun.sync」を使用しないことで、この遅延の短縮を試みました。
StartJobRun.syncを使用しないステートマシンの作成(改善案)
改善案として、「StartJobRun」でジョブを実行した後に「GetJobRun」APIを定期実行し、
ジョブのステータスチェックを実施するステートマシンを作成しました。
今回は10秒おきにジョブのステータスをチェックする設定としています。
定義は以下の通りです。
{
"StartAt": "glue-task1",
"States": {
"glue-task1": {
"Next": "Wait",
"Retry": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"IntervalSeconds": 5,
"MaxAttempts": 3
}
],
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "task-failed"
}
],
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "作成したGlueJobの名前"
}
},
"Wait": {
"Type": "Wait",
"Seconds": ここでステータスチェックの頻度を設定[秒](今回は10),
"Next": "GetJobRun"
},
"GetJobRun": {
"Next": "Job Complete?",
"Retry": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"IntervalSeconds": 5,
"MaxAttempts": 5
}
],
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "task-failed"
}
],
"Type": "Task",
"ResultPath": "$.GetJobRun",
"Resource": "arn:aws:states:::aws-sdk:glue:getJobRun",
"Parameters": {
"JobName": "作成したGlueJobの名前",
"RunId.$": "$.JobRunId"
}
},
"Job Complete?": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.GetJobRun.JobRun.JobRunState",
"StringEquals": "SUCCEEDED",
"Next": "complete"
},
{
"Variable": "$.GetJobRun.JobRun.JobRunState",
"StringEquals": "STARTING",
"Next": "Wait"
},
{
"Variable": "$.GetJobRun.JobRun.JobRunState",
"StringEquals": "RUNNING",
"Next": "Wait"
}
],
"Default": "task-failed"
},
"task-failed": {
"Type": "Fail",
"Error": "Task Failed",
"Cause": "Task Failed"
},
"complete": {
"Type": "Pass",
"End": true
}
},
"TimeoutSeconds": 600
}
StartJobRun.syncを使用したステートマシンの作成
比較対象として、構成自体は変えずにGlueJobの実行に「StartJobRun.sync」を使用したものを作成しました。
{
"StartAt": "glue-task1",
"States": {
"glue-task1": {
"Next": "complete",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "task-failed"
}
],
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun.sync",
"Parameters": {
"JobName": "作成したGlueJobの名前"
}
},
"task-failed": {
"Type": "Fail",
"Error": "Task Failed",
"Cause": "Task Failed"
},
"complete": {
"Type": "Pass",
"End": true
}
},
"TimeoutSeconds": 600
}
検証方法
上記2つのステートマシンから同じGlueJobを実行し、
Glueのコンソール上で確認できるジョブの終了時刻と、Step Functionsの次のステップ「complete」の開始時刻の差を計算して比較しました。
実行するGlueJobはPython Shellタイプで作成し、60秒間待機するだけのコードをScriptに記載しました。
import sys
import time
time.sleep(60)
結果
※2022/08/22実施
.syncを使ったステートマシンの遅延 | .syncを使っていないステートマシンの遅延 | |
---|---|---|
1回目 | 00分37秒 | 00分05秒 |
2回目 | 00分40秒 | 00分05秒 |
3回目 | 00分47秒 | 00分06秒 |
4回目 | 00分53秒 | 00分06秒 |
5回目 | 00分23秒 | 00分01秒 |
6回目 | 00分53秒 | 00分05秒 |
7回目 | 00分52秒 | 00分06秒 |
8回目 | 00分37秒 | 00分05秒 |
9回目 | 00分29秒 | 00分09秒 |
10回目 | 00分37秒 | 00分10秒 |
平均 | 00分41秒 | 00分06秒 |
考察
今回の計測では平均して約35秒の遅延の短縮が確認できました。
.syncを使っていないステートマシンでは最大10秒の遅延が見られましたが、
これはステータスチェックの頻度の設定値以内であり、想定される遅延時間内に収まっています。
GlueJobの実行時間を今回は60秒に固定しているため、他の実行時間では遅延の短縮効果に変化があると考えられますが、許容できる最大の遅延時間をステータスチェックの頻度に設定することで、許容以上の遅延の発生については防止出来ると思います。
また一つのステートマシンで複数回Jobを実行する場合では大幅な時間短縮が見込めそうです。
改善案のデメリット
今回の改善案のデメリットとしては、Step Functions上の実行イベント履歴が見にくくなることが挙げられます。
ジョブの実行に時間がかかる分だけステータスチェックのイベント履歴が増えるので、
運用保守で実行イベント履歴を使用している場合は、探したいログが埋もれてしまう原因になってしまいそうです。。。
※10秒ごとのステータスチェックでは約1分30秒の実行時間で90のイベントが発生
最後に
今回はGlueJobとの連携時の遅延について検証を行いましたが、.syncは他にもECSなどのサービスで使用することが出来るようです。
.syncを使用しているステートマシンで処理時間を短縮したい場合には、今回紹介した方法を試してみてはいかがでしょうか。