AWS Batchを使って時間のかかる処理をサーバーレス化する

時間のかかる処理をオンスポットで実行させるのにベストな環境とは

時間のかかる処理を実装する必要がありました。 ユーザからのリクエストを起点としてスタートする処理なのですが、時間がかかる重い処理でユーザをずっと待たせる訳には行かないので非同期処理にする必要がありました。

Ruby on Railsで動いているWEBアプリだったので、Sidekiqを使って非同期処理を行うというのが一つの方法でしたが、Sidekiqを使って管理をすると負荷のかかるサーバの面倒を見たりする必要があって色々と大変です。そこで、やはりサーバーレス化したいですよね。

AWSのLambdaを使って処理を行いたいですが、Lambdaは5分以上の処理は出来ないのです。さて、どうしたものか…と思ったところ、 AWS Batch というサービスの存在を知り、これがまさにピッタリでした。

AWS Batchとは

About AWS Batch

AWS Batchとは、5分で終わらないような時間のかかる重い処理をフルマネージドな環境(細かい管理が不要!)で実行できます。Dockerのコンテナを準備しておけば、その上で実行できるのでとても自由度も高いです。

AWS Batchについて(AWS公式)

全体のアーキテクチャ

この記事を参考にして実装しました。

大雑把にフローを書くとこのようになります。

  1. API Gatewayへ ジョブのリクエストを送る

  2. 連携させたLambdaが起動

  3. LambdaがBatchのジョブキューにジョブを追加

  4. Batchのジョブがスタート

  5. サーバが起動。この時、ECSのコンテナを使って環境も構築される

  6. 実際に動くコードはAWS CodeCommitからPullして、それを実行する

  7. 完了

開発時のフロー

  • Lambdaへジョブキューへジョブを追加する処理を書く

  • API GatewayでそのLambdaへAPIからアクセスできるようにする

  • Pythonで書いた実行させる中身のコードは、AWS CodeCommitへPushしておく

  • 使用するDockerコンテナを作成しておく。準備できたらコンテナイメージをECSへ追加

  • Batchにて、環境の作成、ジョブの定義作成

全体をうまく連携して動かさないといけないので、少々ややこしく思いますが、一度作り上げると分かると思います。

結果どうだったか

結果、とても良いです。負担が重いようなら、同時実行する数を設定で増やせば大丈夫ですし、サーバは起動した分しか料金も発生しないので素晴らしいです。サーバレスの良い所がそのまま活かせます。

サーバの運用というのは意外と面倒なことが多いものですが、そういった負担がなくなるというのはとても大きなメリットです。

ぜひ試してみてください👍

@takp