初めて触るAWS Batch

2018.11.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS上でバッチ処理を実行する方法は色々考えられますが、AWSにはそのものズバリな名前のAWS Batchというサービスがあり、これを使うことでお手軽にバッチ処理を実行することができます。今回、AWS Batchを初めて触ってみましたので、その内容について調べたところをまとめました。

AWS Batchとは

AWS Batchとは、re:Invent 2016で発表された、AWS上でバッチ処理を実行・管理するフルマネージドサービスです。実行する処理の内容や実行するインスタンスの種類などを設定すると、自動的にインスタンスを確保して処理を実行してくれます。

AWS Batchでは、ユーザは4つのコンポーネントを定義します。以下の記事が参考になります。

ジョブ

AWS Batchで実行する作業単位で、後述するジョブ定義ジョブキューを指定するものです。ジョブを「送信」すると、ジョブ定義に書かれた処理が指定されたジョブキューで順次実行されていきます。

ジョブ定義

実行する処理の内容を定義するものです。具体的には、使用するdockerイメージと実行するコマンドを指定します。 下記は初回実行時のウィザードで作られる最も簡単なジョブ定義で、echo 'hello world'を実行します。

{
    "jobDefinitionName": "first-run-job-definition",
    "jobDefinitionArn": "arn:aws:batch:ap-northeast-1:123456789012:job-definition/first-run-job-definition:1",
    "revision": 1,
    "status": "ACTIVE",
    "type": "container",
    "parameters": {},
    "containerProperties": {
        "image": "busybox",
        "vcpus": 2,
        "memory": 2000,
        "command": [
            "echo",
            "'hello world'"
        ],
        "volumes": [],
        "environment": [],
        "mountPoints": [],
        "ulimits": []
    }
}

ジョブキュー

ジョブを登録するキューです。ジョブキューは下記のコンピューティング環境と紐付けます。あるジョブキューに登録されたジョブは、そのジョブキューと紐付いているコンピューティング環境で実行されます。

コンピューティング環境

ジョブを実行するEC2インスタンスの確保方法を指定します。大きく分けて以下の2通りがあります。

  • マネージド EC2インスタンスをAWSが自動的に確保するやり方です。通常はこちらを利用するのがお手軽です。オンデマンドインスタンスとスポットインスタンスを選ぶことができます。
  • アンマネージド EC2インスタンスをユーザが自分で用意するやり方です。

ジョブの並列実行 - 配列ジョブ

同じ処理を複数の入力データに対して実行したいことがあります。AWS Batchには配列ジョブという機能があり、同じジョブ定義で複数のジョブをまとめて実行することができます。

配列ジョブには公式のチュートリアルがありますので、これに沿って配列ジョブの実行方法を解説してみます。

ジョブ定義

以下のファイルを入れたdockerイメージを作成します。

colors.txt

red
orange
yellow
green
blue
indigo
violet

print-color.sh

#!/bin/sh
LINE=$((AWS_BATCH_JOB_ARRAY_INDEX + 1))
COLOR=$(sed -n ${LINE}p /tmp/colors.txt)
echo My favorite color of the rainbow is $COLOR.

※チュートリアルには記載がありませんが、実行権が必要です。chmod +x print-color.shをお忘れなく。

Dockerfile

FROM busybox
COPY print-color.sh /tmp/print-color.sh
COPY colors.txt /tmp/colors.txt
ENTRYPOINT /tmp/print-color.sh

print-color.sh にある変数AWS_BATCH_JOB_ARRAY_INDEXが配列ジョブの特徴です。配列ジョブで同時に送信されるジョブにはそれぞれ0から始まるインデックスがつけられ、その値が環境変数AWS_BATCH_JOB_ARRAY_INDEXにセットされます。配列ジョブのジョブ定義では、この値を使って処理内容をどうにかして分けることになります。

ここで作成したdockerイメージを使って、ジョブ定義"print-color"を以下のように定義します。

print-color.json

{
  "jobDefinitionName": "print-color",
  "type": "container",
  "containerProperties": {
    "image": "aws_account_id.dkr.ecr.region.amazonaws.com/print-color",
    "vcpus": 1,
    "memory": 250
  }
}

ジョブ

上記のジョブ定義"print-color"と適当なジョブキューを指定してジョブを送信します。この時、配列サイズを指定することで配列ジョブになります。下記は配列サイズを7とした例です。

print-color-job-def.json

{
  "jobName": "print-color",
  "jobQueue": "first-run-job-queue",
  "arrayProperties": {
    "size": 7
  },
  "jobDefinition": "print-color"
}

配列ジョブを実行してみた例としては、以下の記事も参考になります。 [アップデート]AWS BatchでArrayジョブに対応しました #reinvent

ジョブの定期実行 - CloudWatchイベントとの連携

バッチ処理は、毎日◯時に実行など定期的に実行したいことが多いものです。 AWS Batchは、CloudWatchイベントをトリガーとしてジョブを送信する機能により、ジョブを定期的に実行することができます。

CloudWatchでイベントを作成し、そのターゲットとして"Batch job queue"を指定することで、イベントをトリガーとしたジョブの送信ができます。具体的な手順などは下記の記事に全て書かれていますので、ご参照ください。 [アップデート]AWS BatchがCloudWatch Eventsに対応しました!時間起動も可能に

まとめ

以上、AWS Batchの機能について、自分が触った範囲でまとめてみました。これ以外にも、ジョブの依存関係を指定したり、失敗したジョブを再試行したりすることもできます。うまく使いこなせば、バッチ処理をかなりお手軽に実行できるようになると思います。参考になれば幸いです。

参考文献