レック・テクノロジー・コンサルティング株式会社TECH BLOG

AWS Batchで長時間かかる処理を実行してみる

AWS上で長時間かかるプログラムを実行したいけれど、Lambda には最大実行時間15分という制限があり使えない。かといって専用のECSタスクやEC2インスタンスを作るのは大袈裟すぎる。どうしよう...

そんなときにもってこいなのが AWS Batch です。本記事では、実際にそのような状況で AWS Batch を利用した際の設定手順やトラブルシューティングについてご紹介します。

AWS Batch とは?

AWS Batch は、フルマネージドのバッチ実行サービスです。Fargate, EC2, EKSといった基盤を選択でき、コンテナイメージを用意するだけで簡単にバッチ処理の実行基盤を作成することができます。

事前準備

Batch にリソースをデプロイするにあたり、ECR にコンテナイメージを用意しておきます。

image.png

プライベートリポジトリとローカル環境間におけるイメージのpull&pushについてはこちらの記事をご参照ください。

今回は上記の「dev-km_loader」を使用します。

ジョブ設定

ジョブ設定の手順は以下の通りです。

  1. ジョブ定義
  2. コンピューティング環境作成
  3. ジョブキュー作成
  4. ジョブ作成

ジョブ定義の内容をもとに、指定したコンピューティング環境でリソースが作成され、ジョブキューに送信されたジョブを実行するイメージです。

ジョブ定義

最初にジョブとオーケストレーションの設定を行います。

オーケストレーションタイプは推奨の「Fargate」を設定します。ジョブ定義の構造は、「従来の containerProperties 構造を使用」で作成するとログ出力されない問題があったため、チェックを外してレガシー構造で作成することにします。

image-1.png

続いてジョブ定義の設定を行います。

image-2.png

上記で設定した項目は以下の通りです。

  • 全般設定
    • 名前:ジョブ定義名
  • タスクプロパティ
    • 実行ロール:ユーザの代わりにECSタスクを実行するロール。ecsTaskExecutionを指定
    • エフェメラルストレージ:タスクに割り当てられるストレージの量

なお、タスク実行ロール「ecsTaskExecutionRole」に付与している権限は以下の通りです:

  • AmazonEC2ContainerRegistryReadOnly
  • AmazonECSTaskExecutionRolePolicy
  • AmazonS3ReadOnlyAccess
  • SecretsManagerReadWrite

次にコンテナ設定を行います。

image-3.png

上記で設定した項目は以下の通りです。

  • 名前:任意のコンテナ名
  • イメージ:参照するコンテナイメージのURI
  • リソースの要件
    • CPU:コンテナに割り当てるvCPUの数
    • メモリ:コンテナに割り当てるメモリ容量
  • ロギングの設定
    • ログドライバー:awslogs

ロギングの設定はオプションですが、今回はコンテナのログを CloudWatch に送るためログドライバーに「awslogs」を指定しておきます。Pythonアプリケーションの場合、loggerやprintで標準出力/標準エラー出力に出力された内容を対象にログが収集されます。

最後に設定を確認し、問題がなければ「ジョブ定義を作成」をクリックして完了です。

コンピューティング環境作成

コンピューティング環境はジョブ定義と同じく「Fargate」を選択します。

image-4.png

インスタンス設定では、Fargate Spot 容量を使用するかを選択できます。スポットインスタンスを利用する Fargate Spot の場合、コストを大幅に節約できるとのことです。

最大vCPUはジョブ定義と同じ2としています。

image-5.png

ネットワーク設定では、実行環境のVPC、サブネット、セキュリティグループなどの設定を行います。

image-6.png

設定を再度確認し、問題がなければそのまま作成を行います。数分待ち、「Valid」となればOKです。

image-7.png

ジョブキュー作成

続いてジョブキューの作成を行います。

オーケストレーションタイプは「Fargate」とし、「接続されたコンピューティング環境」には上記で作成したコンピューティング環境を指定します。

image-8.png

ジョブ作成

作成したジョブ定義とジョブキューを設定します。

image-9.png

その他の設定はデフォルトのまま進み、「ジョブを送信」をクリックします。

ジョブを送信すると、ジョブの実行が開始されます。

image-10.png

ジョブ定義で awslogs の設定を行った場合、CloudWatchの/aws/batch/jobs配下にジョブのログイベントが出力されます。

image-14.png

補足:ジョブを呼び出して実行

Step Functions には Batch:SubmitJob があり、ジョブ定義とジョブキューをもとにジョブを実行することができます。他の処理と組み合わせて実行したい場合に便利です。

image-13.png

トラブルシューティング

ジョブ実行に失敗

以下のエラーが出た場合、ECSとECRの通信が正しくできていません。

ResourceInitializationError: unable to pull secrets or registry auth: The task cannot pull registry auth from Amazon ECR: There is a connection issue between the task and Amazon ECR. Check your task network configuration.

対策として、コンピューティング環境のネットワークの設定を見直します。今回の場合、セキュリティグループのアウトバウンドのすべての通信を許可することで解決しました。

タスク実行に失敗

「Essential container in task exited」でタスク実行に失敗した場合、アプリケーションになんらか問題がある可能性があります。主に以下の原因が考えられます。

  • アプリケーション内でエラーが発生し落ちた
  • アプリケーション内の処理を行うのに必要なタスクロールが設定されていない

いずれの場合も CloudWatch のログからエラーログを確認し、適切な対処を行います。

※タスクロールはコンテナのアプリケーション実行時に利用されるロールです。例えばS3バケットからのデータ取得や DynamoDB への書き込みなどが必要な場合、それらに対応する権限をもつタスクロールを設定する必要があります。

AWS Batch の場合、ジョブ定義の「タスクロール」で設定可能です。

image-12.png

image-11.png

課金について

AWS Batch 自体に料金はかからず、基盤として利用するサービス(ECS, EC2, EKS)に対してのみ料金が発生します。

今回の場合は Fargate なので、CPU、メモリ、エフィメラルストレージのコストの合計が請求対象の料金となります。こちらの例と同様に計算すると、求める料金は以下のようになります。

サービスが1つのECSタスクを使用し、月に一度約30分間(1800秒)実行されて、その間にECSタスクが2vCPU、16GBのメモリ、21GBのエフィメラルストレージを利用する場合:

  • CPU:1 * 2 * $0.000014044 * 1800 * 1 = $0.05
  • メモリ:1 * 16 * $0.00001536 * 1800 * 1 = $0.04
  • ストレージ:1 * (21 - 20) * $0.0000000369 * 1800 * 1 = $0.00

より、月額料金は $0.09 = 13円(1ドル140円)

※上記は東京リージョンの場合

激安です。

さいごに

AWS Batch について、実際の例をもとに詳しくご紹介しました。

AWS Batch は Lambda のような実行時間制限がなく、フルマネージドで手軽に運用できる便利なサービスです。Lambda と違い自分でコンテナイメージを用意する必要はありますが、そのひと手間も苦に感じないくらいの良さがあります。

「AWS Batch を初めて知った」「Lambda でやろうと思ってあきらめた処理がある」という方は、ぜひ AWS Batch の利用も検討してみてください。

参考

この記事をシェアする

  • Facebook
  • X
  • Pocket
  • Line
  • Hatena
  • Linkedin

資料請求・お問い合わせはこちら

ページトップへ戻る