はじめに
Lambdaでは処理時間の制限(最大15分)やメモリ制限により、大量データの一括処理や重たいバッチ処理には不向きなケースがあります。
そこで今回は、AWS BatchとECS Fargateを組み合わせて、必要なときだけスケーラブルに起動するバッチ処理基盤を構築する方法を紹介します。
この構成のメリット
✅ サーバーレスでインフラ管理不要
✅ 処理時間の制限なし(Lambdaの15分制限を超えられる)
✅ 使った分だけの料金(処理していない時はコスト0円)
構成概要
以下のような構成で、LambdaからAWS Batchをトリガーし、ECS Fargateでタスクを一時的に起動します。
+-------------+ +---------------+ +-------------------+
| Lambda +--------->+ AWS Batch +--------->+ ECS Fargate Task |
+-------------+ +---------------+ +-------------------+
↑ | |
| v v
[トリガー] +-------------+ [処理実行]
| Job Queue |
+-------------+
各コンポーネントの役割
- Lambda: バッチ処理のトリガー(API GatewayやEventBridgeから呼び出し)
- AWS Batch: ジョブのスケジューリング・起動管理
- ECS Fargate: コンテナ実行環境(インスタンス不要)
- ECR: Dockerイメージを登録
実際のユースケース例
- 数十万件のCSVデータを集計・変換してS3に出力
- データベースへの一括登録処理
- 外部APIとのバルク連携
- 画像や動画の一括変換処理
実装に必要なAWSサービスと設定
1. Amazon ECR(Elastic Container Registry)
目的: バッチ処理のDockerイメージを保存する
設定手順:
- ECRでリポジトリを作成
- Dockerイメージをビルドしてプッシュ
# イメージのビルドとプッシュ例
docker build -t my-batch-app .
docker tag my-batch-app:latest [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-app:latest
docker push [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-app:latest
TypeScriptでバッチ処理を実装する場合のDockerfile例:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
CMD ["node", "dist/index.js"]
2. IAMロールの作成
目的: バッチジョブの実行に必要な権限を付与
必要なロール:
- Batch Service Role: AWS Batchサービス用
- ECS Task Execution Role: タスク実行用(ECRからイメージ取得など)
- ECS Task Role: アプリケーション用(S3アクセスなど)
3. AWS Batchの設定
① Compute Environment(計算環境)の作成
設定内容:
- タイプ: Fargateを選択
- 最大vCPU: 必要に応じて設定(例: 256)
- サブネット: VPCのサブネットを指定
- セキュリティグループ: 適切なものを選択
② Job Queue(ジョブキュー)の作成
設定内容:
- 優先度: 1000(デフォルト)
- 計算環境: 上記で作成したものを選択
③ Job Definition(ジョブ定義)の作成
設定内容:
- プラットフォーム: Fargate
- 実行ロール: 作成したECS Task Execution Role
- ジョブロール: 作成したECS Task Role
- イメージ: ECRにプッシュしたイメージのURI
- vCPU: 必要に応じて(例: 4)
- メモリ: 必要に応じて(例: 8GB)
4. Lambdaからバッチジョブを起動
Lambda関数の実装例(TypeScript):
import { BatchClient, SubmitJobCommand } from '@aws-sdk/client-batch';
import { APIGatewayProxyHandler } from 'aws-lambda';
const batchClient = new BatchClient({ region: 'ap-northeast-1' });
export const handler: APIGatewayProxyHandler = async (event) => {
try {
// バッチジョブを送信
const command = new SubmitJobCommand({
jobName: 'my-batch-job',
jobQueue: '作成したジョブキュー名',
jobDefinition: '作成したジョブ定義名',
containerOverrides: {
environment: [
{ name: 'INPUT_FILE', value: 's3://my-bucket/input.csv' },
{ name: 'OUTPUT_FILE', value: 's3://my-bucket/output.csv' }
]
}
});
const response = await batchClient.send(command);
return {
statusCode: 200,
body: JSON.stringify({
jobId: response.jobId,
message: 'バッチジョブを開始しました'
})
};
} catch (error) {
console.error('Error submitting batch job:', error);
return {
statusCode: 500,
body: JSON.stringify({
message: 'バッチジョブの開始に失敗しました'
})
};
}
};
必要なパッケージのインストール:
npm install @aws-sdk/client-batch
npm install --save-dev @types/aws-lambda
5. (オプション)その他の設定
S3バケット
- バッチ処理で使用するデータの格納場所
- 入力ファイル・出力ファイルの保存先
EventBridge
- 定期的なバッチ実行が必要な場合
- Cron式でスケジュール設定可能
実装時のポイント
コスト面
- Fargateは使用した分だけ課金
- Spot Fargateを使えばさらに安く(最大70%OFF)
処理時間
- Lambdaと違い時間制限なし
- 数時間かかる処理も実行可能
スケーラビリティ
- 同時に複数のジョブを並列実行可能
- Compute Environmentの設定で最大同時実行数を制御
よくあるトラブルと対処法
| 問題 | 対処法 |
|---|---|
| ジョブが開始されない | VPCの設定、セキュリティグループを確認 |
| イメージが取得できない | Task Execution Roleの権限を確認 |
| S3にアクセスできない | Task Roleの権限を確認 |
まとめ
AWS Batch + ECS Fargateの組み合わせは、Lambdaでは対応しきれない重量バッチ処理において、非常に強力な選択肢です。
特に以下のような場合におすすめです:
- 処理時間が15分を超える
- 大量のメモリが必要
- 既存のDockerアプリケーションを活用したい
サーバーレスでありながら、柔軟で強力なバッチ処理基盤として、ぜひ活用してみてください。