AWS ParallelCluster 要求した台数分のスポットインスタンスが起動しないときの挙動を知ろう

クラウドHPC環境として利用しているAWS ParallelClusterでスポットインスタンスで計算リソースを要求した際に指定した要求数を確保できませんでした。そのときParallelClusterはどのような動きをするのかを観察していたので紹介します。
2021.10.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS ParallelClusterを利用したクラウドHPC環境では計算リソースはほぼ無制限に使えます。「計算リソース無限」と言われると逆にコストが気になります。計算リソースにあたるコンピュートノードではスポットインスタンスを活用することで計算リソースの利用料金を最大90%割引で利用できます。

普段からスポットインスタンスを利用しているわけですが「はじめてジョブ投入時に必要なCPU数分のスポットインスタンスが揃わない」状況に遭遇しました。どういった動きをするのか観察しましたので紹介します。

まとめ

  • コンピュートノードが必要台数分揃わないときは、以下のどちからを確認すると理由がわかりスッキリする
    • CloudTrailからRunInstancesイベントを確認
    • ヘッドノードのslurm_resumeログを確認
  • 必要台数揃うまでの間、起動中のコンピュートノードは待機しているだけで計算は一切しない
  • スポットインスタンスの空き容量はあるときはあるし、ないときはない
    • 故に格安で同スペックの計算リソースを使わせてもらえると考えたほうが素直
    • Slurmのパーティション単位で単一のインスタンスタイプしか指定できないため、なおのことスポットインスタンスの確保が難しい側面もある

検証環境

項目
AWS ParallelCluster 3.0.0
Job Scheduler Slurm
OS Ubuntu 20.04 LTS
CPU AMD
Head Node c5a.large
Compute Node c5a.4xlarge(16vCPU)

以下の検証時に利用したクラスターです。クラスターの設定ファイルは以下のリンクに載せています。

状況

128CPU必要なジョブを登録しました。指定したパーティションは16vCPUのインスタンス(c5a.4xlarge)をスポットインスタンスで利用しています。

squeueで確認すると16vCPU * 8ノード = 128vCPUになるため、8ノード要求していることがわかります。状態はPD(Pending)です。必要数の計算リソースを待っています。

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                 4  cpu-spot     bike   ubuntu PD       0:00      8 (BeginTime)

8台中5台起動してきました。バラけて起動してくるのをはじめて目撃しました。あと3台必要ですのでしばらく待ってみます。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
cpu-spot*        up   infinite      3  idle% cpu-spot-dy-c5a4xlarge-[9-11]
cpu-spot*        up   infinite     12  idle~ cpu-spot-dy-c5a4xlarge-[6-8,12-20]
cpu-spot*        up   infinite      5   idle cpu-spot-dy-c5a4xlarge-[1-5]
high-cpu-spot    up   infinite     10  idle~ high-cpu-spot-dy-c5a24xlarge-[1-10]

30分ほど待つと追加で2台起動してきました。8台中7台揃いました。あと1台必要です。さらにしばらく待ってみます。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
cpu-spot*        up   infinite      1  down# cpu-spot-dy-c5a4xlarge-19
cpu-spot*        up   infinite     12  idle~ cpu-spot-dy-c5a4xlarge-[6-8,11-18,20]
cpu-spot*        up   infinite      7   idle cpu-spot-dy-c5a4xlarge-[1-5,9-10]
high-cpu-spot    up   infinite     10  idle~ high-cpu-spot-dy-c5a24xlarge-[1-10]

追加された2台を青枠で囲んでいるように見せかけています。インスタンスIDでのソート関係で本当はこの2台ではないのですが、7台起動していることが伝われば十分です。

最初のコンピュートノード起動から1時間弱経過しましたが8台揃いません。EC2の左ペインからスポットリクエストを確認します。作成日の欄からざっとスポットインスタンスのコンピュートノードの起動時間を確認できます。

待機中の7台分のコンピュートノード利用費がかかります。scancelでジョブをキャンセルしました。

結果の振り返り

ジョブの実行には128vCPU分の8ノード必要です。最初の30分間は5台起動し後半の30分弱は合計7台のコンピュートノード起動していました。この間に計算は行われていたのでしょうか?

正解は「なにもやってなくただ起動している」です。

7台起動して112vCPUもあれば計算処理できるのではないかと思いますが、必要台数分揃わないとジョブは実行されません。ちなみに8台揃うと6分半で計算の終わったジョブでした。7台でも10分もあれば終わったのでは?と言いたくなりますが、ジョブを投げる前に128vCPUを想定して並列計算用に分割する処理を施していました。仮に計算してくれたとしても単純に台数が減って正しく処理できていたのか別の問題を抱えそうです。

原因調査

スポットインスタンスを利用しているため、スポットインスタンスを確保できなかったことが原因だと予想はつきますが根拠となるログを確認します。

CloudTrail確認

CloudTrailからイベント名RunInstancesを指定し検索します。該当時間帯付近を確認してください。エラーコードの列が表示されていない場合は右側にある歯車アイコンから設定で表示列を選択できます。

イベント名をクリックすると詳細を確認できます。

イベントレコード抜粋

...snip...
    "eventTime": "2021-10-08T13:08:59Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "RunInstances",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "13.112.222.171",
    "userAgent": "Boto3/1.18.36 Python/3.7.10 Linux/5.11.0-1016-aws Botocore/1.21.36",
    "errorCode": "Server.InsufficientInstanceCapacity",
    "errorMessage": "There is no Spot capacity available that matches your request.",
...snip...

「リクエストに一致するスポット容量がありません」のメッセージを確認できます。

"There is no Spot capacity available that matches your request.

参考

slurm_resumeログ確認

ヘッドノードの/var/log/parallelcluster/slurm_resume.logをログインし確認してもよいのですが、せっかくなので自動生成されるCloudWatchダッシュボードから確認してみます。

同様にThere is no Spot capacity available that matches your request.のメッセージを確認できます。

2021-10-08 13:29:31,048 - [slurm_plugin.instance_manager:_launch_ec2_instances] - ERROR - Failed RunInstances request: 32cb1f34-c6c6-433c-84f1-ecb26c1a8b52
2021-10-08 13:29:31,048 - [slurm_plugin.instance_manager:add_instances_for_nodes] - ERROR - Encountered exception when launching instances for nodes (x1) ['cpu-spot-dy-c5a4xlarge-7']: An error occurred (InsufficientInstanceCapacity) when calling the RunInstances operation (reached max retries: 1): There is no Spot capacity available that matches your request.

調査結果

コンピュートノードで要求した8台のスポットインスタンスは、1時間のうちに7台までは確保できたが残り1台は確保できなかった。つまり、EC2サービスでc5a.4xlargeをスポット起動できる空きキャパシティが該当時間帯にはなかった。

数時間後に改めて

同じジョブを登録しました。8ノードの要求をかけています。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
cpu-spot*        up   infinite      8 alloc~ cpu-spot-dy-c5a4xlarge-[1-8]
cpu-spot*        up   infinite     12  idle~ cpu-spot-dy-c5a4xlarge-[9-20]

需要と供給の問題で今回は最初から8台同時起動してきました。本件に遭遇するまではこのパターンしか見たことはありませんでした。

倍の16台を要求しても「空きがあるときはある、ないときはない」なので16台同時起動してきました。ParallelClusterの場合は単一のインスタンスタイプを複数台要求することになるため、なおのことスポットインスタンスの確保が難しい側面もあります。

おわりに

スポットインスタンスの空きキャパシティがなく起動してこないのか、コンピュートノードのクラスターの設定を誤っていて起動してこないのか切り分けに困るかもしれません。CloudTrailか、slurm_resumeログからコンピュートノード(EC2インスタンス)起動処理時のエラーログがないか確認してみると切り分けの手助けになります。

参考