Fargate VS Lambda 両者の違いをスタートアップCTOが本気で考えてみた!~2021年9月29日更新

Fargate VS Lambda 両者の違いをスタートアップCTOが本気で考えてみた!~2021年9月29日更新

こんにちは!

Docker による開発がデファクトな近年では、Fagate による Docker 開発が多くなってきました。わたしたちの開発でも Fargate は多くの例で採用しており、最近では EC2 を SSH で操作するのには抵抗を感じます。すっかり Fargate の魅力に取り憑かれていますね。

しかし最近、お客様から下記のようなご質問をいただくケースが多くなってきました。

「 Lambda と Fargate はどう使い分けるの?」

「 Lambda の方が簡単!Lambda で済ませたいけどどうかな?」

これを理解するには、まず両者の違いをしっかり理解する必要があります。

AWS Fargate は何者?

AWS Fargate は、コンテナオーケストレーション用のサーバー( 例えば EC2 を自前で構築し Docker デーモンを管理するサーバー )を自身で管理することなく、Docker コンテナ実行を実現できる AWS サービスです。

Docker コンテナーの起動、停止、Latest への差し替えなどをマネージすることが可能です。

また Code Piepline と接続することも可能なので、私たちはよく Code Build で Dockerfile をビルド→ ECR へ Latest タグのイメージをプッシュ→ ECS でタスクを実行し連携させることが多いです。

ここで、わたしたちが考える Fargate を理解する上で最も重要なポイントは、「 Fargate は実際には AWS ECS でコンテナーを実行する方法の1つにすぎない」ということです。( ECS は EC2 インスタンスでの実行中のコンテナと Fargate の両方をサポートしています )

Fargate はDocker コンテナーを使用してアプリケーションを実行しますが、コンテナーは ECS タスク( Kubernetes のポッドと同様 )として実行され、タスクはサービス( Kubernetes デプロイメントと同様 )によって管理されます。

また、Fargate は Elastic Load Balancer へのターゲットグループに連動が可能です。そのため HTTP トラフィックを受信できますが、この方法の場合は Fargate のタスクが生きていないとトラフィックに対してレスポンスを返せず、ELB が504タイムアウトエラーを返却してしまいます。サービスでタスクを管理する際に必要タスク数を必ず1以上に設定しましょう。( スケジュールで起こすアーキテクチャーも可能です )

この点は、Lambda と API Gateway のコールドスタート問題と似ていますが、Fargate の場合は実行中のタスクをリアルタイムで監視することができる上、ECS 上でコンテナーのログを見ることができます。障害の切り分けが非常にしやすく、一時的に起動するタスクの定義を差し替えるなど柔軟に対応をすることが可能です。

AWS Lambda は何者?

AWS Lambdaは、サーバーをプロビジョニングすることなく、近年のマイクロアーキテクチャーのように小さな機能単位でソースコードをデプロイ・実行できるサービスです。

  • 開発者はソースコードをアップロードするだけで実行可能
  • 様々なAWSサービスのイベントと接続可能
  • サーバーレスの性質により実行後にサーバーインスタンスが破棄されるためセキュア

Lambda で使用されるサーバーインスタンスは一時的なもので、実行時にのみサーバーが起動し、実行完了後に起動したサーバーインスタンスは削除されます。( すぐには消えず、次のリクエストを一定時間待機する様子 )

つまり Lambda は永続的なサーバーではありません。例えば PHP Laravel や Java PlayFramework などのセッションをサーバー内のローカルファイルに指定している場合は、障害を引き起こす可能性があるので注意が必要です。(そもそもフレームワークのような多種多用な機能を持つソースコードをLambdaへデプロイして実行すること自体反対ですが…)

Fargate VS Lambda のユースケース

わたしたちは主に、PHP や Java 言語のフレームワーク、大規模なバッチジョブを実行する際は Fargate、小粒のイベントを処理する際は Lambda を採用しています。

  • Lambda は大規模な処理を実行するのは苦手、制約との戦いになることがしばしば( 例えば PHP Laravelのようなフレームワークを実行するのは不得意 )
  • Lambda は様々な AWS リソースのイベントを取得することが可能で実装が関数単位なので導入が簡単
  • Fargate は ELB などのネットワーク( VPC )に依存するサービスのデプロイが必要なので VPC 周辺知識&設計が必要
  • Fargate はローカル開発とインフラ環境を Docker で統一化できるので開発とインフラを疎結合にできる( デプロイ後に不具合がほぼない )

重要なのは、Lambda は付き合い方を間違えるとしばしば苦しむことがあります。例えば、Nuxtjs などを Lambda へデプロイして SSR し、API Gateway へレスポンスするケースを想像してください。

もし Nuxtjs で Ant-Design などの UI フレームワークと AWS SDK などの大容量のバンドルファイルを返却しようとした場合は、確実に Lambda のレスポンスサイズの制約に引っかかりエラーとなります。( 下手したらデプロイサイズの制限に引っかかりデプロイできません… )

Lambda は基本的にマイクロサービス的なユースケース(冪等性のある小さな処理)で使いましょう。例えば、S3 にアップロードされた画像のサムネイル生成、AppSync や APIGateway の CRUD 系の小さな API 処理などです。

Lanbda の導入を検討されている方は、必ず Lambda の制約を確認しておいてください。

Lambda と Fargate どっちが高い?

前提として Lambda と Fargate は完全に別々の課金モデルを使用しているため、コードを実行する際の料金を比較することは困難です。もしこれを明確にしたい場合は、実際のワークロードを想定し、Lambda と Fargate それぞれの課金体系に合わせてコストを試算する必要があり、多くの時間を要します。(実際のワークロードでの料金を確認するためには両方を実際に試す必要があります)

Fargate の料金体系

Fargateは、1時間あたりの CPU とメモリの使用に対して課金されます。最新の価格情報はこちらをご覧ください

高いスケールで非常に予測可能なワークロードで使用する場合、Fargate だけに依存するのではなく、EC2 インスタンスを使用して一部の ECS タスクを実行することも可能です。EC2 タスクの実行の場合「サーバーレス」の側面は失われますが、スポットインスタンスまたは予約済みインスタンスを使用すると、EC2 を大幅に安価にできます。EC2 の価格情報はここにあります

Lambda の料金体系

Lambda は、リクエスト数、メモリ、関数実行の秒数の組み合わせで課金されます。最新の価格情報はこちらをご覧ください。

Lambda コストを節約したい場合は、関数のメモリ要件のサイズを適切に設定することがとても重要です。512Mb のメモリを使用するように関数を構成しても、実行中に 128Mb しか消費しない場合、基本的に各呼び出しのコストが4倍に増加しています…。

Lambda を初めて使用する場合は、CloudWatch 請求アラームをセットアップし、Lambda による想定以上の請求を回避する方法があります。

Lambda 関数のログを参照すると、呼び出された Lambda の使用メモリと実行時間を確認できますので確認してみてください。

また、Lambda 関数が Kinesis などのイベントストリームからトリガーされる場合は、バッチサイズを設定し、呼び出しの数も減らすことができますので、こちらも合わせて検討してみてください。

比較してみた所感

途中にも書きましたが、やはり小粒処理は Lambda、大きな処理は Fargate やその他の AWS サービスを活用することを推奨します。( 例えばストリーミング処理であれば KinesisDataStream など )

特に Lambda はサーバーレスな料金体系からスタートアップ開発には最適だと言えますね。ユーザー数の少ないリリース直後などはほぼ課金されず、コストを抑えることが可能です。( Lambda は実行量で課金)

Fargate・サーバーレス開発はお気軽にお問い合わせください。