Amazon Web Services ブログ
AWS Batch ベストプラクティスまとめ
この記事はプリンシパル HPC ソリューションアーキテクトの Pierre-Yves Aquilanti、AWS Batch のプリンシパルプロダクトマネージャの Steve Kendrex とプリンシパル HPC アプリケーションエンジニアの Matt Koop によるものです。
更新: 2021 年 10 月 5 日 セクション 2 に於けるサブネット CIDR ブロックのガイドラインを修正。
AWS Batch は、科学者や技術者が複雑なシステム構成を管理する必要なく、自由にスケールできる計算環境を提供するサービスです。2017 年に登場して以来、疫学、ゲームシミュレーション、大規模機械学習といった諸々のワークロードを稼動させる様々な業種や組織といったお客様に採用されてきました。
この投稿では、色々なお客様向けに計算環境の最適化をしてきた経験を元に、私達が作り上げたベストプラクティスと実践的ガイドラインを紹介します。AWS Batch で Amazon EC2 スポットインスタンスを使う事でコスト面での最適化をする方法や、問題が発生した場合どのように対応すれば良いのか、コンテナを利用した大規模な構成を学ぶことができるでしょう。
1. EC2 スポットインスタンスを賢く使ってコスト最適化
Amazon EC2 スポットは、オンデマンドインスタンス比で最大 90% 割引されるという特徴により、バッチ処理のワークロードのコストを抑える目的で多くの場合利用されます。Amazon EC2 スポットのベストプラクティスでは、この購入モデルの利点をどのように活かすかという一般的な指針を提供しています。この一般的な指針を、AWS Batch でどのように適用できるかについては、以下の情報を追加で確認して下さい。
- 正しい分配戦略を選ぶ。
BEST_FIT
では AWS Batch は最もコストの安いインスタンスタイプを優先して選択します。BEST_FIT_PROGRESSIVE
では、BEST_FIT インスタンスが、要求された全てのキャパシティを満たせない場合に追加のインスタンスを起動します。SPOT_CAPACITY_OPTIMIZED の場合、充分なEC2 スポットキャパシティプールからインスタンスを選択します。SPOT_CAPACITY_OPTIMIZED
は中断が懸念される場合にお勧めです。しかも EC2 スポットによるコスト削減の利益を享受できます。コストを最適化したいのであればBEST_FIT_PROGRESSIVE
が考慮すべきオプションです。 - インスタンスタイプに多様性を持たせる。例えば c5.12xlarge が適したインスタンスだとして、互換性のある他の全てのサイズ (c5.24xlarge 等) やファミリー (c5a、c5n、c5d、m5、m5d 等) も含めておけば、価格や利用可能なインスタンスの状況に基づいて必要なものを AWS Batch が選択します。
- 複数のアベイラビリティゾーンを使う。AWS Batch 環境を設定する際に、異なるアベイラビリティゾーンに跨がるサブネットを使うようにします。リージョン内の全てのアベイラビリティゾーンを使うことで AWS Batch が複数のインスタンスプールを利用可能になり、スポットインスタンスの中断が発生するリスクを低下します。
- ジョブの実行時間を短くする或いはチェックポイントを使う。実行に数時間かかるようなジョブは EC2 スポットに不向きです。何故なら、数分から数十分で終わるようなジョブに比べて中断による影響が著しく大きいからです。もし、ジョブをより小さな複数のジョブに分割できるか、実行途中でチェックポイントを作れるのであれば、総体として見た場合の中断の影響は低下します。
- 自動再試行を使う。AWS Batch はサービスエラーやスポットインスタンスの再利用等により、ジョブがゼロではない終了ステータスで終わった場合、最大 10 回まで自動再試行することができます。再試行パラメータを最低 1 回から 3 回に設定して下さい。もしジョブが中断した場合、そのジョブはジョブキューの先頭に配置され優先的にスケジュールされます。再試行戦略は、ジョブ定義の作成時もしくは以下の例のように AWS CLI でジョブを投入する際に設定可能です。
aws batch submit-job --job-name MyJob \ --job-queue MyJQ \ --job-definition MyJD \ --retry-strategy attempts=2
- 再試行設定をカスタムする。ジョブの再試行戦略はアプリケーションに於ける特定の終了ステータスや Amazon EC2 スポットの再利用状況に合わせてカスタム可能です。以下の例では、ホストが原因でジョブが失敗した場合は最大 5 回再試行を許可していて、それ以外の理由で失敗した場合には失敗を宣言した上でジョブを終了します。
"retryStrategy": { "attempts": 5, "evaluateOnExit": [{ "onStatusReason" :"Host EC2*", "action": "RETRY" },{ "onReason" : "*" "action": "EXIT" }] }
スポットの中断を追跡したい場合、Spot Interruption Dashboardというサーバレスアプリケーションを AWS アカウントに導入して下さい。これは、どの EC2 スポットインスタンスが中断され、どのアベイラビリティゾーンに存在するかに関する統計情報を提供します。
2. よくあるエラーとトラブルシューティングの流れ
AWS Batch でエラーが発生した原因としてしばしば上げられるのは、ジョブの前提条件に合致していないインスタンスの設定であったり、アプリケーションレベルでのエラーです。その他の一般的な問題として、ジョブが RUNABLE の状態でスタックしたり、AWS Batch の計算環境が INVALID 状態でスタックしたりする事があります。
AWS Batch の詳細な設定をする前に、次のチェックリストに目を通して下さい。
- 現在利用している環境の EC2 スポットインスタンスの vCPU の起動可能上限が要求しているキャパシティよりも小さくないか (例: 現在の vCPU 上限が 256 の状態で 10000 vCPU のワークロードを実行しようとしていないか)。必要に応じて Service Quotas ダッシュボードから制限緩和申請をして下さい。これは新規アカウントで良く見過されがちな設定です。
- ジョブがアプリケーション実行前に
DockerTimeoutError
やCannotPullContainerError
で失敗する場合は、こちらのガイドを見て解決する事ができます。 - ジョブを実行する VPC やサブネットの残り IP アドレス数が充分ではない場合、実行したいワークロードに必要なだけの IP アドレスが確保できる CIDR を設定して下さい。必要に応じて、広いアドレス空間を持つ専用 VPC を作成して下さい。以下の例では複数の VPC を
10.x.0.0/16
の CIDR で作成し、その中にサブネットをアベイラビリティゾーン毎に10.x.y.0/17
の CIDR で作成しています。x には 1-4 の数字が、y には 0-128 の数字が入ります。この構成であれば 36000 個の IP アドレスがそれぞれのサブネットで確保されています。
このチェックリストを使ってもまだ問題が解決していない場合、以下の項目も確認して下さい。
- AWS Batch ダッシュボードで、ジョブの状態が予想通りのものかを確認した上で、ジョブの送信時にコンピューティング環境がスケーリングされているかどうか確認して下さい。Amazon CloudWatch でジョブのログを見る事もできます。
- Amazon EC2 コンソールのインスタンスの項目で、インスタンンスが作成されている最中かどうか確認して下さい。これは、AWS Batch によってインスタンスが要求され、スケーリングが発生している予兆です。もし一つもインスタンスが一覧に無い場合、Auto Scaling グループの履歴を確認して、コンピューティング環境のサブネット設定を変更する必要があるかどうかを特定する必要があります。別の要因としては、投入したジョブに必要なリソースが一つのインスタンスに収まり切らない事もあります (例えば 1TiB のメモリを要求する単一のジョブを、最大 192GiB メモリの C5 ファミリーで実行する設定になっている場合)。
- Auto Scaling グループの履歴を見て、AWS Batch によって要求されたインスタンスが存在しているか確認して下さい。これによって EC2 がどのようなインスタンスを確保しようとしているかが分かります。EC2 スポットは時折、特定のアベイラビリティゾーンで指定したインスタンスを確保できないというエラーを出力します。しかし問題ありません、スポットインスタンスプールのキャパシティはアベイラビリティゾーンによって異なり、特定のインスタンスファミリーが提供できない場合があります。
- インスタンスが ECS に登録されているかを確認して下さい。EC2 パネルにインタンスが表示される場合であっても、ECS コンテナのインスタンスが ECS クラスタに登録されていないのであれば、これはカスタム AMI に ECS エージェントがインストールされていない可能性があります。EC2 の User Data か起動テンプレートの設定を確認して下さい。このような場合は、別の EC2 インスタンスを作成して根本原因を特定するか、SSH または AWS Systems Manager のセッションマネージャーを利用して既存のインスタンスに接続して調査して下さい。
- 実行時に問題が発生し再現が容易ではない場合は、CloudWatch エージェントをインストール・設定して、システムログと ECS ログを CloudWatch Logs に出力する事で後から確認できるようにします。そのためにはカスタム AMI を構築するか、カスタム起動テンプレートを作成する必要があります。それでもまだエラーの原因を特定できない場合は、サポートを契約しているならサポートへチケットを起票して下さい。AWS のフォーラムで AWS Batch や HPC について検索することも、原因究明の一助になるかもしれません。フォーラムを利用する場合、ワークロードの詳細、構成、実行したテストとその結果など問題に関する充分な情報を提供する事を忘れないで下さい。これにより問題解決の時間を短縮できます。トラブルシューティングをしやすくするために、オープンソースの監視ソリューションを使用する事もできます。これらのダッシュボードを通じて AWS Batch 環境の全体像を捉える事ができるようになります。
3. コンテナと AMI の最適化
コンテナのサイズと構造は最初の段階で実行しようとしているジョブによって決まります。特にコンテナが 4GB よりも大きい場合は顕著です。コンテナイメージは Docker によって並列に取得されるレイヤに組み込まれています。デフォルトではこのレイヤを取得するために 3 つのスレッドが使用されます。その並列度を上げたい場合は Docker のmax-concurrent-downloads
のパラメータを変更して下さい。コンテナのサイズと構造を最適化するのは良い選択肢です。AWS Batch を使用する際の推奨設定は以下の通りです。
- 小さなコンテナは素早く取得でき、また始動も高速です。あまり頻繁に更新されないファイルやライブラリは AMI 側にオフロードし、bind mountを利用してコンテナに提供します。これによりコンテナをスリムにして、ジョブの起動時間を短くします。
- サイズが均一なレイヤを作成するか大きなレイヤを分割する。それぞれのレイヤは一つのスレッドで取得されるので、レイヤサイズが大きい事はジョブの起動時間に顕著な影響を与えます。レイヤ毎に最大 2GB というのは良い妥協点です。コンテナイメージの構造やレイヤのサイズを調べるには次のコマンドが利用できます。
docker history your_image_id
- AWS Batch ジョブ用コンテナリポジトリとして Amazon ECR を使う。独自にオンプレミスのサーバや EC2 上に構築したリポジトリは数千のジョブを並列で稼動させる環境には対応できません。他方でパブリックリポジトリは同時アクセス制限などのスロットリングが発生し得ます。ECR であれば小規模な環境から 100 万 vCPU を超える大規模な環境まで対応しています。
4. 大規模に実行するためのチェックリスト
AWS Batch で 5 万 vCPU を超えるようなワークロードを実行する前に、以下のチェックリストに目を通して下さい。100 万 vCPU のような大規模ジョブを計画している場合や、大規模処理のガイダンスが必要な時は、AWS チームにお問い合わせ下さい。
- AWS マネジメントコンソールの Service Quotas パネルで EC2 の制限を確認し、必要に応じて、ピーク時に想定される EC2 インスタンス数分の制限緩和申請をして下さい。忘れてはいけないのは、Amazon EC2 スポットインスタンスとオンデマンドインスタンスでは別々の制限がある事です。
- 実行するリージョンの EBS クォータを確認して下さい。GP2、GP3 の EBS ボリュームは、各インスタンスのオペレーティングシステムが使用します。リージョン毎のクォータはデフォルトで 300TiB に設定されていて、全てのインスタンスがこのクォータの一部を消費しています。この上限に達すると、それ以上インスタンスを作成できなくなります。
- ストレージとして S3 を利用する。S3 は高いスループットを提供し、どのアベイラビリティゾーンでどれくらいのインスタンスやジョブが稼動しているかという状況に応じてプロビジョニングする量を変更する必要もありません。このページ内にある推奨事項に従ってパフォーマンスを最適化して下さい。
- ボトルネックを素早く特定できるよう徐々に規模を大きくする。100 万 vCPU でいきなりジョブを動かすのではなく、最初は 5 万 vCPU、20 万 vCPU、50 万 vCPU と徐々に規模を拡大して下さい。
- 大規模に実行するとアーキテクチャやアプリケーションが何かが上手く動かない可能性があります。これは 1,000 vCPU から 5,000 vCPU への増加の場合でも発生し、疑わしくない部分に出現する事もあります。モニタリングする事で潜在的な問題を素早く特定しする事ができます。Amazon CloudWatch Logs でログデータを、CloudWatch の埋め込みメトリックフォーマットでクライアントライブラリのメトリクスをモニタリングできます。
5. どんな場合 AWS Batch が適合するかしないか
AWS Batch は、無料でスケーラブルなキューイング機能とコスト最適化されたスケーリング性能によって低コストで大規模なジョブを実行する事を目指しています。しかしながら全てのワークロードが AWS Batch に向いているわけではありません。特に——
- 非常に短いジョブ。ジョブがわずか数秒で完了するような場合、ジョブをスケジュールするためのオーバーヘッドがジョブ自体の実行時間よりも長くなる可能性があり、期待よりも効率が低くなる可能性があります。ワークアラウンドとしては、処理群をまとめたものをジョブとして AWS Batch に投入し、ジョブ内で処理群を順次実行する方法があります。ジョブを処理群にまとめる一般的なガイドラインは、1) 個別のタスクの引数を Amazon DynamoDB のテーブルに書き込むかファイルとして Amazon S3 バケットに保存します。AWS Batch ジョブが 3-5 分程度持続するようにグループ化するのが理想です。2) AWS Batch ジョブ内のタスクグループをループします。
- 即時に実行する必要のあるジョブ。AWS Batch はジョブを迅速に処理しますが、あくまでバッチスケジューラでありすぐに実行するのではなく、コストや優先度、スループットを最適化しようとします。つまり AWS Batch がこういった最適化を行なえるようにするためには、ある程度の時間ジョブがキューイングされる方が望ましいという事です。ジョブ送信から実行までミリ秒から数秒の範囲の応答時間が必要な場合は、バッチ処理のアーキテクチャではなく Amazon ECS や Amazon EKS を使ったサービスベースの手法が向いているかもしれません。
6. Farget か EC2 か、オンデマンドかスポットか、それが問題だ
AWS Farget と Amazon EC2 選択のはざま
AWS Fargate が向く場合:
- 30 秒以内でジョブを起動する必要がある
- GPU を使わない、4 vCPU 以下で 30GiB 以下のメモリ利用量のジョブ
Fargate は EC2 よりも設定が少なく、初めて使用するユーザにはより簡単に使う事ができます。条件の完全な一覧は AWS Batch のドキュメントで確認できます。
Amazon EC2 が向く場合:
- インスタンスの選択をより高いレベルで制御する必要がある
- AWS Fargate が提供していないリソース、例えば大量のメモリや vCPU、GPU、Amazon Elastic Fabric Adapter といったものが必要な場合
- より高いスループットや並列度が必要なワークロード
- カスタム AMI や EC2 起動テンプレート、あるいは Linux の特殊なパラメータが必要な場合
EC2 はワークロードをチューニングするための手段が豊富で、必要に応じて大規模な処理も可能です。Fargate は使い勝手の良さを求める方や、EC2 が提供する機能を必要としない方に好まれています。
Amazon EC2 オンデマンドとスポットのはざま
AWS Batch を使っているお客様のほとんどは、オンデマンドよりも節約できるので、Amazon EC2 スポットを利用しています。しかしながらオンデマンドは、数時間に渡って実行されるワークロードや中断する事ができないワークロードにとっては良い選択肢です。ワークロードが EC2 スポットとオンデマンドのどちらに適合するかを判断する鍵となる条件の一覧を以下に記載します。スポットの利用をためらう事はありませんし、必要に応じてオンデマンドへ切り替える事も柔軟に検討して下さい。
Amazon EC2 スポットに向く場合:
- ジョブの継続時間が数分から数十分程度の場合
- ワークロード総体として潜在的な中断に強く、ジョブの再スケジューリングが容易な場合
- 長時間かかるが、中断が発生してもチェックポイントから再開可能なジョブ
Amazon EC2 オンデマンドが向く場合:
- ジョブの実行時間が 1 時間から数時間かかり、また中断が許容されない場合
- 厳格なサービスレベル評価基準 (SLO) があり、ワークロード総体として計算時間の増加を許容できない場合
- 必要とするインスタンスによっては中断の可能性が上昇
最初はスポットを使ったジョブを投入し、失敗した場合オンデマンドを使うといった両方を混ぜて使うケースもあります。ジョブ投入を開始した段階では、キューは EC2 スポット上のコンピュート環境に接続しています。もしジョブが中断した場合、Amazon EventBridge からイベントを受取り、それがスポットインスタンスの再配置に関連していたのであれば、AWS Lambda や AWS Step Function を使用して、ジョブをオンデマンドキューに再投入します。注意しなければいけないのは、オンデマンドコンピューティング環境では、異なるインスタンスタイプ、サイズまたはアベイラビリティゾーンを使用する必要がある事です。そうしないと、EC2 スポットインスタンスプールが枯渇し、中断発生率が増加してしまいます。
まとめ
この記事では、ゲノミクス、金融サービス、自動運転開発等の分野に於けるお客様とのやり取りを通じで得られた AWS Batch に関するベストプラクティスについて紹介しました。このベストプラクティス集を通じて、Amazon EC2 スポットの活用方法、AWS Batch で実行されるワークロードのトラブルシューティング方法、AWS Batch アーキテクチャを最適化する方法について説明しました。
他のベストプラクティスや秘訣を見付けた場合は、気軽にコメントか HPC のウェブページでご連絡下さい。サービスのページに加え、HPC ワークショップと AWS ワークショップのウェブサイトにアクセスすれば、AWS Batch の詳細を知る事ができます。
この記事は 2021 年 10 月 4 日に投稿された「AWS Batch Dos and Don’ts: Best Practices in a Nutshell」をソリューションアーキテクトの小野が翻訳したものです。