BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【AWS】Fargate・Lambda・Batchの使い分け

こんにちは!
BFT名古屋支店の、佐野です。

最近年末あたりから年明けにかけて始まる案件についての打ち合わせが多くなってきており、その為の調べ物や資料の作成に力を入れております。
その中で「AWSのサーバレスコンピューティングサービスであるFargate、Lambda、そしてBatchはどう違うのか、どれを使うべきなのか」という話が出てきていたのですが、サーバレスの運用上多くの人が気になるところだと考え、折角なので今回の記事としてもお送りしようかと思います。


はじめに

さて今回はFargate・Lambda・Batchの使い分けというところですが、実はこの3つの中でひとつだけ、他と単純に比較できないものがあります。
以前「AWSのサーバーレスアーキテクチャ」について記事にしましたが、それについて読まれている方、あるいは詳しい方であれば分かるかもしれません。
そう、AWS BatchはFargateやLambdaと違い、正確にはサーバーレスサービスの分類に入っていないサービスなのです。
BatchもFargateと同じくコンテナベースのコンピューティングサービスですが、細かく言えばその点がまず違うと言えます。

ではそれを踏まえた上で、Fargate・Lambda・Batchそれぞれの特徴をまとめていきます。


Fargate・Lambda・Batch それぞれの特徴

まずは、三者それぞれの大まかなサービス提供内容をおさらいします。

  • Lambda

AWS公式によれば、Lambdaとはサーバーを必要とせずコード(プログラム)を実行することができるコンピューティングサービスとあります。
例えばAWS上でアプリケーションを稼働させる場合、その実行環境となるサーバーを構築した上で、実行環境上でアプリケーションを開発する必要があります。
しかしサーバーレスサービスのひとつであるLambdaは実行環境となるサーバーを必要とせず、コードを記述するだけでAWS上で実行することができます。
勿論サーバーなしにコードが動いている訳ではなく、裏側でAWS全体の実行環境を利用しています。
筆者の中では、コードを実行する時だけ一時的に実行環境を間借りしているものだと思っています。

またLambdaは実行のトリガーを設定することで、様々なAWSサービスのイベントに反応して自動的に実行させることもできます。
例えばS3にファイルが置かれた時にLambdaが実行されるようなトリガーを設定しておき、その置かれたファイルを読み込んで他のAWSサービスに内容を飛ばした後、そのファイルを削除する、と言ったことが可能です。
処理に必要なメモリ量も設定が可能で、メモリ量に応じて使用されるCPUが高性能になっていきます。

とはいえ、Lambdaには様々な制約が存在し、またメモリ割り当てに関しても限界値があります。
特に関数のタイムアウト時間、実質的な実行時間の制約は厳しく、15分(900秒)を過ぎるとLambdaは処理を強制的に止めてしまします。
またAPI Gatewayと連携させる場合は呼び出しペイロード、特にレスポンスサイズの制限を考慮しなくてはなりません。
筆者においても、Lambdaの実行時間制限については頭を悩ませたことがあり、大きなプロセスをLambdaで実行しようという時にはこういった制約をどう凌ぐかという検討を行なうことが多いイメージがあります。

Lambdaの詳しい制約については、AWS公式の「AWS Lambda のクォータ」を参照ください。

  • Fargate

AWS公式によれば、FargateはElastic Container Service(以下ECS)とともに使用し、サーバーやクラスターを必要とせずコンテナを実行できるサーバーレスコンピューティングエンジンとあります。
まずここで出てきたECSというのは、EC2インスタンス上に配置されたDockerコンテナに対して実行・停止の操作を行なうことができるサービスです。
なので利用する為にはコンテナの実行環境とするインスタンスが必要となりますが、Fargateを利用することでインスタンスを必要とすることなくコンテナの実行・停止を行なうことができます。 Lambdaがコード、ないし関数の実行環境を提供するものであれば、Fargateはコンテナ、ないしコンテナの実行環境を提供するものであると言えるでしょう。

ただしFargateはあくまでサーバーレスのコンテナ実行環境を用意するものであり、コンテナで実施するアプリケーションやタスクの管理はECS上で行ないます。
最初に“サーバーレスコンピューティング「エンジン」”とした通り、Fargateはサービスとして存在しているのではなく、ECSに付随している機能、あるいはECSでコンテナを実行する方法の1つであると言えます。

  • Batch

AWS公式によれば、BatchはAWS上でバッチコンピューティングワークロードをあらゆる規模で行なえるフルマネージド型サービスとあります。
バッチコンピューティングというと「定期バッチを行なってくれるものなのかな」と考える方もいると思います。(筆者がそうでした)
正確に言えばそれも含まれますが、もっと大きな枠を取っているものです。
Batchで言う「バッチコンピューティング」とは“あらかじめ定義しておいた一連の動作を実行させるもの”のことを言います。
これは作業実行時に実行者が張り付いて対応することなく処理を完遂する、という本来のバッチ処理の意味合いと一致しています。

Batchではこの“一連の動作”を「ジョブ」として定義し、あらかじめ設定したコンピューティング環境でジョブを実行します。
そのコンピューティング環境のリソースはBatchの処理内容に応じてオートスケーリングされるEC2インスタンスであり、処理が完了次第インスタンスが削除される仕組みとなっています。
またこのバックグラウンドではECSが動いているのですが、EC2インスタンス共々ユーザーが意識することがないようラッピングされています。
ただ一時的にでも仮想マシンであるEC2を展開するので、その存在を意識する必要がある都合上サーバーレスでないとされているのも頷けます。

つまりBatchとはECSやEC2といったAWS上の他のサービスをジョブ内容に合わせて利用し、その管理をユーザーが行なうことなくバッチ処理を実行できるサービスなのです。
他のサービスとの併用が前提となり、併用先のサービスで料金が発生するため、Batchの利用そのものには料金は発生しないのも特徴です。

またごく最近となって、Batchを利用する際にリソースとしてEC2ではなくFargateを使用する選択肢が追加されました。(2020/12/4 アップデート)
Fargateを使用することで先に述べたEC2の存在を意識する必要がなくなるため、よりサーバーレスの概念に寄った形でBatchを利用することができるようになっています。


どういう時にどれを使う?

Fargate・Lambda・Batchの3つで共通しているのは「インフラ構築、管理へ割く時間を削減することでアプリケーションの開発・運用に専念できる」という点ですが、ではこれらをそれぞれどういったケースで使っていくべきなのでしょうか。
まずはそれぞれの特徴を分かりやすく挙げてみましょう。

  • Lambda

    • 関数単位のコードを記述するのみで実装できるため、構築が容易であり導入障壁がコンテナを利用するものより低い。
    • CloudWatch Eventsを初めとした他サービスでのイベントをトリガーにし、自動的に実行できるため、スケジューリングも行ないやすい。
    • 制約の上限があまり大きくなく、特に実行時間が長くなりがちな処理や多くのプロセスを処理するといったことは不向き。
  • Fargate

    • Fargateを利用するECSはコンテナベースのコンピューティングサービスであるため、処理させたい内容を含むDockerイメージが事前に必要。
    • 処理実行上での制約は少なく、制限をほぼ気にする事なく大きな処理を実行する事が可能。
    • ECS上でタスクを一元管理する事ができ、同時に実行中のタスクをリアルタイムで監視することができる。
  • Batch

    • Fargateの場合と同様、ECSを利用するため、処理させたいバッチアプリケーションを含むDockerイメージが事前に必要。
    • EC2を利用する場合は、オートスケーリングされるとはいえEC2における様々な要素を考える運用が必要となる。
      (ただしこの点はBatchでFargateを利用することで解消可能となった)
    • ECSを利用する場合はECSのサービスクォータの都合上、並列処理数が10までとなってしまうが、Batchを利用する場合はその制限がない。

こうすると、3つを使う時のシチュエーションがうっすらと見えてくる気がしますね。

つまりLambdaは「長い時間をかけない処理を小規模で、あるいはとりあえず動かしたい場合」に向いており、
比べてFargateは「Lambdaでは手に余るような中規模な処理を、特に定期実行するような場合」に使うべきものであり、
そしてBatchは「大規模かつECSのサービスクォータを越える数の並列処理を要するバッチ処理を行なう場合」に必要であるもの、と言えます。

またBatchは12/4のアップデートによりFargateを利用できるようになったことで、Fargateとは比較対象というより併せて使うことを検討する関係になったと言えるかもしれません。
どちらかと言えばBatchの比較対象はFargateより「ECS単体で使う場合」である気がします。

LambdaとFargateに関しては間違いなく比較対象であり、筆者としては「Lambdaで済ませられるものはLambdaで」「そうでないならFargate(ECS)を使う」と言った分け方となると考えています。
一般的には“Lambdaではぎりぎり処理できないかもしれない……”という時に、余裕を持ってFargateを選択するというケースも多いようです。
また料金的な観点で言えば、LambdaとFargateに関しては料金形態が異なり、実際のケースに当てはめて検討しないと、どちらが安価となるか一概には言うことができません。
加えてLambdaもFargateも、処理を行なう量や時間によってはサーバーレス特有の「使い過ぎると固定費であるEC2の方が安くなる」というデメリットも抱えているため、そことの比較検討も必要となります。


最後に

今回3つのサービスに注目し、色々比較を行ないましたが、やはりというかAWSのサービスはすべて存在するべくして存在しているのだなと感じました。
単純な、あるいは殆ど上位互換下位互換のような関係にあるものはなく、規模や細かなシチュエーションに応じて、効率的に利用するべきサービスをよく検討し、選択を行なう工程はやはり抜けないようです。
今回の通りLambda、Fargate、Batchどれについても「これひとつあればいい」というものではありませんので、やりたいことをよく加味してどの方法を取るかはよく考えたいところです。