初めてのAWS Batch – 利用時に考慮したことやったことまとめ –
コンニチハ、千葉です。
AWS Batchを導入する機会があり、やったこと、設計したことなどをまとめました。
AWS Batchってなに?は、こちらにまとめましたので御覧ください!前提知識として必要になります。 本エントリーでは、設計時に考えたことをまとめます!
ECR
Dockerコンテナを格納するリポジトリが必要になります。プライベートリポジトリであるECRを利用しましょう。リポジトリを利用する認証もIAMロールで対応できるのでシンプルに利用できます。 AWS Batch環境の作成前に、リポジトリを作成しダミー用コンテナイメージをアップしておきましょう。
IAMロール
必要なIAMロールです。AWS Batch作成前に事前に作成しました。EC2のインスタンス用とコンテナ用の2種類が必要になります。
EC2インスタンス用ロールとしては、「AmazonEC2ContainerServiceforEC2Role」ポリシーをアタッチします。 コンテナ用については、コンテナで利用するポリシーをアタッチします。
AMIの作成
Batchで起動されるECS用のAMIを用意します。デフォルトだとAmazon ECS-Optimized Amazon Linux AMIで起動されます。ディスク容量を変更したり、インスタンスストアを利用したい場合はカスタムAMIを作成する必要があります。
今回は、インスタンスストアを利用する環境でしたので以下のようにAMIを作成しました。
ECSオプティマイズAMI(Amazon ECS-Optimized Amazon Linux AMI)よりEC2を作成し、
- ユーザーデータに以下を指定
#!/bin/bash yum update -y echo '#!/bin/bash' > /var/lib/cloud/scripts/per-boot/initial_instance_store.sh echo 'mkfs -t ext4 /dev/xvdb;mount /dev/xvdb /media/ephemeral0' >> /var/lib/cloud/scripts/per-boot/initial_instance_store.sh chmod 750 /var/lib/cloud/scripts/per-boot/initial_instance_store.sh
-
ボリューム設定でインススタンスストアを追加(インスタンスストア:/dev/sdb)
-
インスタンスを停止しAMIを作成
このAMIをAWS Batchで指定します。
AWS Batch環境の構築
ここでようやくAWS Batchの管理コンソールから操作を行います。
Compute environments
Compute environmentsを作成します。これは起動するEC2に関する環境定義となります。
ポイントとしては、vCPUsの設定になります。ここの設定はAutoScalingに反映されます。例えばですが、EC2:コンテナを1:1で起動させたい場合は、コンテナで指定するvCPUs・メモリサイズを、利用するインスタンスサイズとイコールにします。例えばですが、
環境:r3.xlarge(vCPUs4、メモリ30.5GB)、コンテナのリソースもvCPUs4、メモリ30.5GB メモリ29GB等に設定
実際にインスタンスで利用できるメモリは30.5GBより小さくなる場合があり、EC2が自動で起動しなくなることがありました。そのため、スペックより小さい値でメモリを設定します
Min:0 ※0にするとジョブキューがない場合はEC2は0。r3.xlargeの場合は4に指定すると1インスタンスが起動する、8にすると2インスタンスが起動する。 Max:40 ※最大40にすると、最大で10インスタンスが起動します。
Minを0にすると、キューがない場合EC2インスタンスが0になりリソース費用がかかりません。逆に、ジョブ実行時にEC2インスタンスの起動が必要になるためラグが発生します。システムに応じて変更する必要があります。 Min、Maxはコンテナをどれくらい起動させるかを考えながら指定します。
Job queues
ジョブキューに関する定義です。ジョブキューには、Compute environmentsで作成した環境を指定できます。また、Compute environmentsに優先順位をつけて複数指定できます。そのため、常時EC2を2台起動、追加でスポットインスタンスも利用みたいな構成もとれます。
Job definitions
起動するコンテナを定義します。これは、ECSのTask定義と同等と考えて大丈夫そうです。コンテナで利用する、コンテナのリソース(vCPUs、メモリ)、コンテナイメージ、実行コマンド、ローカルディスクのマウント設定などができます。また、リトライ回数も定義可能です。これらを決める必要があります。
Job
ジョブ実行時に渡す変数を決めましょう。ポイントは、手動でリトライするときに簡単にできるように設計することです。例えば、ID:999の処理を再実行したい場合、コンテナの環境変数にID:999を渡したときに同じ処理を実行できれば再実行しやすいですよね。また環境に依存値も環境変数で渡します。テスト環境や本番環境で固有な値(例えばDB接続情報など)あたりも環境変数に登録できると柔軟性が高いでしょう。この他にもアプリケーションによって、必要なパラメータがあれば適宜環境変数で指定し、コンテナが処理できるように設計します。
エラー時の通知
アプリケーションエラー時の通知用として、 SNSを作成しました。アプリケーションにてエラー時はSNSを利用してメール通知するようにします。
※コンテナ用のロールに「AmazonSNSFullAccess」をアタッチが必要です
ログ出力
アプリケーションで必要なログは、標準出力に出力するように設定します。こうすることで、自動でCloudWatch Logsへログが登録されます。エラー時のデバックや解析用に設定しておくとよいでしょう。 またCloudWatch Logsに保存すると、S3、Kinesis、Elasticsearch Serviceとも連携できます。
キューの監視
処理依頼が沢山来た場合、キューが滞留します。滞留したらアラートがほしいですよね。 ただ、今のところAWS BatchではCloudWatchと連携の機能がないので、アラートが必要な場合はLambdaで実装する必要があります。boto3で確認したところlist_jobsでジョブのステータスを指定してジョブを取得できそうです。「RUNNABLE」になっているジョブの数をカウントすれば、滞留していないかを確認できそうです。
最後に
AWS Batchを利用する上で考慮したことをまとめました。SQSを利用した構成より簡単に実装できたので、バッチ処理が必要な場合はAWS Batchを使っていきたいです。