CTOの椎名です。最近弊社では家族アプリFammの印刷・配送・通知など様々な処理を使うために AWS Lambda と AWS Batch を使う量が増えてきて、ECS Fargate も徐々に導入をはじめてきました。
Lambda も Batch も ECS Task も、何かのジョブを単発/定期でサーバー無しで実行するための手段として似ているところがあります。何かのバッチ/ジョブを作る時に「これはLambdaで作るべきか?Batchで作るべきか?」などで迷う事もあります。もちろん製品名の通り「バッチならAWS Batch」と言う考え方もありますが、AWS Batchではオーバーキルな時もあれば、かゆいところに手が届かない時もあります。
今回はこれらの特徴やメリット/デメリットの比較をまとめます。
AWS Lambda
簡単に言うと「コードだけアップロードして実行トリガーを決めればその通りに動いてくれる」という FaaS(Function as a Service) です。公式の説明は下記の通り:
Lambda を使用すれば、実質どのようなタイプのアプリケーションやバックエンドサービスでも管理を必要とせずに実行できます。コードさえアップロードすれば、高可用性を実現しながらコードを実行およびスケーリングするために必要なことは、すべて Lambda により行われます。
https://aws.amazon.com/jp/lambda/
メリット
- コードのアップロードがとんでもなく簡単
- 実行環境の設定も「メモリ(MB)」や「同時実行数」など最低限の設定だけなのですごく単純
- 実行トリガーのバリエーションが豊富。SNSは使いやすいし、S3/DynamoDBなどの書き込みをトリガーにする事も可能
- CloudWatch Events と連携する事でcronのような定期実行も可能
デメリット
AWS Batch
簡単に言うと「コンテナ化されたバッチ処理を何でも実行できる」というものです。公式の説明は下記の通り:
AWS Batch を使用することにより、開発者、科学者、エンジニアは、数十万件のバッチコンピューティングジョブを AWS で簡単かつ効率的に実行できます。AWS Batch では、コンピューティングリソース (CPU やメモリ最適化インスタンスなど) の最適な数量とタイプを、送信されたバッチジョブの量と具体的なリソース要件に基づいて動的にプロビジョニングします。AWS Batch を使うと、ジョブを実行するためのバッチコンピューティングソフトウェアやサーバークラスターをインストールしたり、管理したりする必要がなくなります。
https://aws.amazon.com/jp/batch/
メリット
- 巨大かつ長時間のバッチ処理を実行可能
- コンテナとコンテナ起動時コマンドを定義する形なので、実行環境は自由。ミドルウェアやディレクトリ構成も柔軟に決定可能
- ジョブ同士の依存関係を定義できるので、「Aが終わったらB」といったワークフローを構築可能
デメリット
- ジョブの修正更新の際は「コンテナを修正→build→ECRにpush」というフローが必要なのでCIなどをきちんと組まないと運用メンテが大変になる。
- スクリプトをS3に配置してコンテナは起動時にS3からコードを取得するようにしておくと運用面はラクになる。弊社はこの手法を採用。こちら参考: https://dev.classmethod.jp/cloud/aws/aws-eaws-ecs-fetch-run-shell/
- ジョブ実行依頼後、キュー処理→インスタンス立ち上げ→ECS Task実行など時間がかかる内部処理が多いので、起動から実行までにかかる時間が不確実。非同期実行なので原理的には当たり前なのだが、1分の時もあれば10分の時もあり、開発中やデバッグの時には若干煩わしく感じる。
- 定期実行の仕組みはない
ECS Task
ECSはAWSのコンテナオーケストレーションのソリューションです。Webアプリケーションを開発運用する上では「ロードバランサーでリクエストを受けて 、長期実行し続けているサーバー複数台が処理を行いレスポンスを返す」という構成が多いと思います(ECSではこれをServiceと呼びます)。 ECSの機能として上記以外にもタスクの単一実行が可能であり、今回の文脈ではその使い方としてのECS Taskについて取り上げます。 公式の説明は下記の通り:
Amazon ECS には、サービススケジューラ (長期実行タスクおよびアプリケーション用に)、タスクを手動で実行する機能 (バッチジョブまたは単一実行タスク用)、および Amazon ECS でクラスターにタスクを配置する機能があります。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/scheduling_tasks.html
メリット
- ECS運用環境では環境整備済みなので、タスク実行は比較的簡単に設定&実行可能
- (AWS Batchと同じく) コンテナ定義および実行環境は柔軟に設定可能
- タスク数も自由に設定可能なので、大量のタスクを一斉に実行するといった事も容易に可能
デメリット
- ECSを使っていないと最初のECSクラスタの構築が大変
- 依存関係のような複雑な制御は不可能
比較
ここまでの特徴を表にまとめるとこのようになります。
AWS Lambda | AWS Batch | ECS Task | |
---|---|---|---|
cron的な定期実行 | ◯ | × | ◯ |
大量データ処理 | × | ◯ | ◯ |
複雑なデータ処理 | × | ◯ | ◯ |
複数ジョブの依存関係制御 | △ | ◯ | × |
何かの操作をトリガーにした実行 | ◯ | × | × |
構築・設定のしやすさ | ◯ | △ | × |
このように、それぞれ適しているシーンと適していないシーンがあります。ただECS Taskに関しては「ECS TaskにできてAWS Batchに出来ない事はない」というのがわかります。AWS Batchは内部的にECS Taskを使っているので、これはその通りです。
上記を以って、「バッチやジョブ系の処理に何を使おうか」という意思決定を、いろんなケースに当てはめて考える事が可能になりますね。
- ECSクラスタを運用している&依存関係のない単一のジョブ
- 迷わずECS Taskを使う
- 1ユーザーごとに実行する、比較的小さなジョブ
- 迷わずLambdaを使う
- 大量ユーザーのデータを一斉に処理するジョブ
- 1ユーザーごとに実行する、非常に複雑なジョブ
- 大量ユーザーのデータを一斉に、なおかつ1ユーザーごとの処理も行程が多い複雑なジョブ
まとめ
AWS Batch, Lambda, ECS Task という3つの似たシーンで使えそうなバッチ/ジョブのソリューションですが、きちんと特徴を掴んでおき判断基準を決めておくと、そのつど適切な技術選定が出来るようになると思います。 AWSでサーバーレスなバッチ/ジョブを検討する際にはぜひ参考にしてください。
積極採用中!!
子育て家族アプリFammを運営するTimers inc.では、現在エンジニアを積極採用中!
急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください!
採用HP: http://timers-inc.com/engineerings