🎃

【AWS】AWS Batchにはじめましてしたいひとへ🐶

2023/06/07に公開

概要📝

AWS Batchのコスト、仕組み、基本用語、ポイントについて記載しています。

私のプロダクトではCompute EnvironmentにEC2を採用したので、Fargateを採用した場合の話については記載が足りない可能性があります🙇‍♂️

私はAWSエンジニアとしてまだまだ駆け出しなので、採用される場合は公式ドキュメントやプロダクトの要件を確認しながらお願いいたします🙇‍♂️🙇‍♂️

対象読者🔖

AWS Batchを採用したことがないが、ちょっと興味がある方
AWS Batchってなんとなく名前ださくね? くらいの薄いイメージしかない方

課題感🔥

私が関わっているプロダクトのリリース前の初期インフラ構築にて、下記のような課題があり、検討の結果AWS Batchを採用することになりました。

  • 課題❓

ECS(Fargate)を採用していたが、batchと命名されているものだけが、本番環境でもタスク1個しか起動されていなかった。
委託業社に理由を聞いたところ、「ECSタスクで定期バッチ処理を行っており、タスクを増やすとバッチ処理が重複する可能性があるため難しい」と回答があった。
しかし、このまま放置すればタスク1個だけで単一障害点になってしまうと思ったため、解決したかった。

というわけで、検討開始!! と私は調査を始めました🦜
アプリケーションロジックそのものを直してECSタスクを増やせるようにする、AWS Batch以外を採用する、とかいろんな答えがあると思いますが、ここにはAWS Batchを採用した経緯についてざっくり記載します。

結果として、採用後にAWS Batchのダッシュボードを確認し、本番環境でジョブが失敗したことは1度もなく運用し続けることができました💎

コスト💰

後に記載する「Compute Envitonment」が起動している間の料金が発生します。
Compute Envitonmentが、EC2ならEC2料金、FargateならFargate料金がそのままかかります。

基本用語、仕組み👓

ECSとAWS Batchの比較表⚙️

あくまで要件や使い方によりますので、参考程度にお願いします🙇‍♂️🙇‍♂️

プロパティ ECS AWS Batch
よくある使い方 Dockerコンテナの常時実行を行う Dockerコンテナの定期的な単発実行を行う
定義の仕方 タスク定義 ジョブ定義
バッチ実行の仕方 構築によって、1つのタスクで同時に複数のバッチを実行する場合もある 1つのジョブ(バッチ)に1つのジョブコンテナが割り当てられる
ログ管理 コンテナのログとして、複数のバッチのログが混在する ジョブ(バッチ)ごとにログが分けられている。
ダッシュボードでジョブごとの成功・失敗が可視化されている
再実行 アプリケーションロジックで作成する必要がある 再実行を自動化することも可能。
AWS Batchが失敗を認識して再実行するには条件があるため、AWS Batchでカバーできない部分はアプリケーションロジックで作成
コンピューティングリソース EC2 or Fargate EC2 or Fargate

実際に使ってみて、便利〜〜!!となったのは、「ダッシュボードでジョブごとの成功・失敗が可視化されている」部分です🥝

Lambdaにするかどうかについては、RDSへアクセスするなど複雑なアプリケーションロジックを介すのであればDockerコンテナの方が良いというアドバイスから、今回の課題に対してはECSかAWS Batchの比較を行いました。

全体の仕組み・基本用語⚙️

ざっくりですが、こんな仕組みで、ジョブごとにコンテナを起動して実行してくれます🦌

  • Compute Environment
    公式ドキュメント
    ジョブコンテナを起動するためのコンピューティングリソースのこと。
    Minimum vCPUsを0にしておけば、定期実行の時間以外は起動されません。
    しかし、ジョブ実行の際に、まずCompute Environmentから起動する時間がかかります。

  • job difinition
    公式ドキュメント
    ECSタスクはtask difinitionを元に起動されると思いますが、それのジョブコンテナバージョンです。

  • ジョブコンテナまたはジョブ
    公式ドキュメント
    ジョブ=あるバッチ処理1回のことで、ジョブコンテナはジョブを実行するためのコンテナです。
    ドキュメントでは、ジョブ、ジョブのコンテナ、ジョブキューといった表現で出てくるかと思います。

  • 再試行戦略
    公式ドキュメント
    これを定義しておくと、ジョブが失敗した場合に再試行することができます。
    ドキュメントを参照しながら、要件に応じて設定しましょう。

ポイント💡

私は、Compute EnvironmentにEC2を採用することになりました🍢
その前提で記載してみます。

  • Compute Environmentのポイント

Compute Environmentの起動時間とコストの関係
先ほども書いたように、Minimum vCPUsを0にすれば料金は抑えられますが、起動時間がかかります。
経験者に聞いたところ、EC2にしてMinimum vCPUsを1以上にして常に起動しておく方法をとると、Compute Environmentの起動時間をなくすことができてより早くジョブを実行開始することができるそうです。
(FargateでMinimum vCPUsを1以上にするとどんな感じなのかは実験しておらずわかりません🙇‍♂️)

我々のプロダクトでは、
・5分ごとに実行するジョブが存在すること
・そのジョブに数分程度の誤差しか認められないこと
などを背景に、Compute EnvironmentにEC2にしてMinimum vCPUsを1としました。

Compute EnvironmentのCPU、メモリと、job difinitionのCPU、メモリ

EC2にすると決めたところで、スペックを決めなければいけません。
・数種類あるジョブごとにjob difinitionを作成
・それぞれに必要そうなCPU、メモリをざっくり見積もる
・同時に実行する可能性のあるジョブすべてのCPU、メモリを足した数値を出す
上記を参考に、EC2のインスタンスタイプを決定しました。

  • ジョブの分け方

ジョブ、job difinitionを分ける基準としては以下のようなものを検討しました。
・一連の処理であるものを、同じジョブとする
・実行タイミングが別々の場合、ジョブを分ける
・同じタイミングでも並行して処理したい場合、ジョブを分ける
・エラーになったときに、止まってしまっても、再実行すればリカバリーできるような単位でジョブを分ける

  • 再試行戦略のポイント

再試行する際は、再試行しても問題がないように、冪等性(べきとうせい)などのアプリケーションロジック面に注意しながら実装することが必要だと思います。

  • ダッシュボードのポイント

神ダッシュボードなので、とにかく見て、ありがてぇ〜〜と思えば大丈夫だと思います笑
job difinitionごとに成功・失敗がわけて見られて、さらにリンクをクリックすると、実行時間やステータスを見ることができます。わかりやすいっ🍺🍺

編集後記📝

途中で図を入れましたが、Compute Environmentを理解した時に、あ〜〜〜そゆこと!!!となりました🍣🍣
採用するかは本当に要件によると思いますが、採用される際は改めて調べていただければ幸いです🍒

我々のプロダクトでは、バッチジョブが5分ごとにある要件のせいで若干料金がかさむ結果となりましたが、予算内に収まっていますし一度もジョブが失敗していないことが毎日確認できるのでとても安心です。

まだ一つのプロダクトしか開発したことがないので、さまざまなプロダクトに関わって、もっと勉強していきたいと思います🏆

Discussion