AWS Batch ジョブが RUNNABLE 状態でスタックしたときにジョブの自動キャンセル設定をできるようになりました

2024.03.30

AWS Batch でジョブが RUNNABLE 状態でスタックしたときの対処方法に、今回のアップデートで新しい機能が追加されました。RUNNABLE 状態でスタックしたジョブを EventBridge で検知でき、一部の原因に対してはジョブを自動的にキャンセルできるようになりました。

背景

AWS Batch でジョブをサブミットした後、設定ミスなどの理由で RUNNABLE 状態のままで止まってしまい、後続のステータスに遷移しないことがあります。

参考: Job states - AWS Batch

よくある原因としては、コンピューティング環境の 最大 vCPU 数設定とジョブの要求 vCPU 数の不一致や IAM ロールの権限不足などが挙げられます。

参考: Troubleshoot AWS Batch jobs stuck in RUNNABLE status | AWS re:Post

DevelopersIO にも以下の記事があります。

新機能

今回のアップデートで、以下の新機能が追加されました。

  • RUNNABLE 状態でスタックしたジョブを EventBridge のイベント "Batch Job Queue Blocked" で検知できる
  • ジョブキューに "ジョブの状態制限" を設定することで、一部の RUNNABLE の理由(スタック原因)に対してはスタックしたジョブを自動的にキャンセルできる
  • ジョブが自動キャンセルされた際は、"Batch Job State Change" イベントが発行される

検証

実際に検証してみました。検証のためにジョブをサブミット後RUNNABLE状態でスタックさせる状況を意図的に作成します。今回はコンピューティング環境の最大 vCPU 数を超える vCPU 数を要求するジョブをサブミットしスタックさせます。

コンピューティング環境の最大 vCPU 数を 4 としました。

ジョブをサブミット時に要求する vCPU 数は 4 を超える値とします。

以降の設定ではこちらのジョブをサブミットしてアップデートの動作を確認することとします。

EventBridge で RUNNABLE 状態のスタックを検知

EventBridge の AWS Batch のイベントタイプにBatch Job Queue Blockedが追加されていました。このイベントタイプを使いRUNNABLEでスタックしたジョブを検知した結果を確認します。

{
  "source": ["aws.batch"],
  "detail-type": ["Batch Job Queue Blocked"]
}

ターゲットは CloudWatch Logs にイベントを記録する設定としました。

意図的にRUNNABLEでスタックさせるジョブをサブミットしました。期待どおり放置してもRUNNABLEのままうんともすんとも進みません。

CloudWatch Logs に保存したログを確認します。

statusReason:で以下のメッセージを確認できます。「ジョブキューに関連付けられたコンピューティング環境が、ジョブの CPU 要求数を満たすことができない」ということで原因の説明があります。

"MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE - CE(s) associated with the job queue cannot meet the CPU requirement of the job."
{
    "version": "0",
    "id": "2c0d7c5c-fc63-874a-d2fe-54fe4db06294",
    "detail-type": "Batch Job Queue Blocked",
    "source": "aws.batch",
    "account": "123456789012",
    "time": "2024-03-30T00:49:21Z",
    "region": "ap-northeast-1",
    "resources": [
        "arn:aws:batch:ap-northeast-1:123456789012:job/1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3"
    ],
    "detail": {
        "jobArn": "arn:aws:batch:ap-northeast-1:123456789012:job/1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3",
        "jobName": "devio-0330",
        "jobId": "1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3",
        "jobQueue": "arn:aws:batch:ap-northeast-1:123456789012:job-queue/devio-job-queue",
        "status": "RUNNABLE",
        "attempts": [],
        "statusReason": "MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE - CE(s) associated with the job queue cannot meet the CPU requirement of the job.",
        "createdAt": 1711759556898,
        "retryStrategy": {
            "attempts": 1,
            "evaluateOnExit": []
        },
        "dependsOn": [],
        "jobDefinition": "arn:aws:batch:ap-northeast-1:123456789012:job-definition/devio-job-def-20240308:5",
        "parameters": {},
        "container": {
            "image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
            "command": [
                "sleep",
                "30"
            ],
            "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
            "volumes": [],
            "environment": [],
            "mountPoints": [],
            "ulimits": [],
            "networkInterfaces": [],
            "resourceRequirements": [
                {
                    "value": "32",
                    "type": "VCPU"
                },
                {
                    "value": "2048",
                    "type": "MEMORY"
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {},
                "secretOptions": []
            },
            "secrets": []
        },
        "tags": {
            "resourceArn": "arn:aws:batch:ap-northeast-1:123456789012:job/1d74dae1-5a4e-4d9f-8244-dbe2cfb14dc3"
        },
        "platformCapabilities": [
            "EC2"
        ],
        "eksAttempts": []
    }
}

RUNNABLE状態でスタックしているジョブを EventBridge で検知、イベントログからスタックしている理由まで確認できました。

スタックしたジョブの自動キャンセル

次にジョブキューに "ジョブの状態制限" を設定し、スタックしたジョブを自動的にキャンセルできるか確認しました。

ジョブキューの設定に新たにジョブの状態制限の項目が追加されていました。

現在、設定可能な各理由(statusReason)に対してジョブを自動で停止するまでの時間を設定しました。タイムアウトまでの時間は 10 分 〜 24 時間の間で設定できます。

各理由(statusEeason)と自動キャンセルに対応しているかの確認は AWS ブログの記載がわかりやすかったです。現時点だとジョブがスタックしたことを EventBridge で検知はできても、自動キャンセル設定に対応していないstatusReasonは 2 つ確認できました。

画像引用: Introducing new alerts to help users detect and react to blocked job queues in AWS Batch | AWS HPC Blog

スタックしたジョブの自動キャンセル設定とは直接関係ありませんが、ジョブを打ち切ったというイベントも発行されるためBatch Job State Chageで拾えます。EventBridge のルールを設定してみました。

{
  "source": ["aws.batch"],
  "detail-type": ["Batch Job State Change"]
}

ジョブのスタック時の EventBridge ルールと同様に CloudWatch Logs に保存します。

意図的にRUNNABLEでスタックさせるジョブをサブミットしました。10 分ほど放置するとジョブがFAILEDで終了しました。RUNNABLE状態でスタックせずに打ち切ってくれています。

CloudWatch Logs に保存したログからstatusReason:で以下のジョブのキャンセル理由を確認できます。

"Canceled by JobStateTimeLimit action due to reason: MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE",
{
    "version": "0",
    "id": "d06fa803-b52e-2a1d-f1f7-c08935c494ec",
    "detail-type": "Batch Job State Change",
    "source": "aws.batch",
    "account": "123456789012",
    "time": "2024-03-30T02:00:33Z",
    "region": "ap-northeast-1",
    "resources": [
        "arn:aws:batch:ap-northeast-1:123456789012:job/3df44b1b-1a30-46d8-8f1a-d11c3dfb657a"
    ],
    "detail": {
        "jobArn": "arn:aws:batch:ap-northeast-1:123456789012:job/3df44b1b-1a30-46d8-8f1a-d11c3dfb657a",
        "jobName": "test-devio-0330-cancel",
        "jobId": "3df44b1b-1a30-46d8-8f1a-d11c3dfb657a",
        "jobQueue": "arn:aws:batch:ap-northeast-1:123456789012:job-queue/devio-job-queue",
        "status": "FAILED",
        "attempts": [],
        "statusReason": "Canceled by JobStateTimeLimit action due to reason: MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE",
        "createdAt": 1711763392195,
        "dependsOn": [],
        "jobDefinition": "arn:aws:batch:ap-northeast-1:123456789012:job-definition/devio-job-def-20240308:5",
        "parameters": {},
        "container": {
            "image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
            "command": [
                "sleep",
                "30"
            ],
            "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
            "volumes": [],
            "environment": [],
            "mountPoints": [],
            "ulimits": [],
            "networkInterfaces": [],
            "resourceRequirements": [
                {
                    "value": "32",
                    "type": "VCPU"
                },
                {
                    "value": "2048",
                    "type": "MEMORY"
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {},
                "secretOptions": []
            },
            "secrets": []
        },
        "tags": {
            "resourceArn": "arn:aws:batch:ap-northeast-1:123456789012:job/3df44b1b-1a30-46d8-8f1a-d11c3dfb657a"
        },
        "platformCapabilities": [
            "EC2"
        ],
        "eksAttempts": [],
        "isCancelled": true
    }
}

ジョブキューに設定を追加すれば、一部の理由であればスタックしているジョブを打ち切れることを確認できました。

まとめ

今回のアップデートにより、AWS Batch の運用が楽になりました。

RUNNABLE 状態のジョブを EventBridge で自動検知できるようになり、一部の原因に対してはジョブを自動的にキャンセルできます。 しかし、自動キャンセル対象外の RUNNABLE 理由(スタック原因)もあります。

おわりに

現在自動キャンセルの対象が今後増えていくことを期待しています。とはいえ EventBridge でスタックしたジョブを検知できるようになったため、ユーザー側で独自の実装すれば自動化はできますね。