AWS ParallelClusterはどうやってコンピュートフリートをスケールさせるのか調べてみた

AWS ParallelClusterのコンピュートフリートはAuto Scaling Groupを使ってスケーリングします。 ジョブスケジューラーとどのように連動しながらスケーリングするのか、動作を確認しました。
2020.08.24

AWS ParallelClusterを利用すると、AWS上で簡単にHPC環境を構築できます。

従来のジョブスケジューラ (SGE、Slurm、Torque) を使用してクラスターを構築すると、AWS ParallelCluster は ジョブスケジューラーとAmazon Auto Scaling Group(以下ASG)の両方と連携しながらコンピュートフリートをスケーリングさせます。

スケールアウト・インそれぞれの処理の流れをドキュメント・ソースコードから確認する機会がありましたので、共有します。

スケーリングに関連するコンポーネント・設定

ジョブスケジューラー

ジョブスケジューラーはジョブやジョブを実行するノード情報を管理します。

AWS ParallelCluster はジョブスケジューラーとして AWS Batch と従来型(SGE/Slurm/Torque)に対応しています。 ASG と連動するのは、後者の従来型です。

Amazon Auto Scaling Group(ASG)

Amazon Auto Scaling GroupはEC2インスタンス数のスケーリングを管理します。 コンピュートフリートはこの ASG を利用して管理され、ジョブスケジューラーと連携しながらフリートサイズを増減させます。

フリートサイズに関係するには、以下のパラメーターです。

  • 希望する容量(desired capacity)
  • 最大キャパシティ(maximum)
  • 最小キャパシティ(minimum)

Amazon SQS

Amazon SQSはメッセージキューサービスです。 コンピュートノードの追加・削除とジョブスケジューラーの連携は、このSQSを介しておこなれます。

jobwatcher プロセス

ジョブスケジューラーと通信し、スケールアウトが必要か判断するプロセスです。

ヘッドノードで実行されます。

sqswatcher プロセス

ノードの追加・削除時には、SQSにメッセージ送信されます。

これらメッセージを受け取り、ジョブスケジューラーなど連携するプロセスです。

ヘッドノードで実行されます。

nodewatcher プロセス

コンピュートノードがジョブを処理しないまま一定期間(AWS ParallelClustter設定ファイルのscaledown_idletime)をすぎた場合、ノードを終了させるプロセスです。

コンピュートノードで実行されます。

compute_ready プログラム

コンピュートノードのブートストラップ処理完了を SQS にメッセージ送信するプログラムです。

プログラムのパスは /opt/parallelcluster/scripts/compute_ready です。

AWS ParallelCluster の設定ファイル

コンピュートフリートのスケーリングに関係するパラメーターは以下です。

  • initial_queue_size : コンピュートフリートの初期起動数
  • max_queue_size : コンピュートフリートの最大起動数
  • maintain_initial_size : フリートの最低起動数を制御。true の場合は最小は initial_queue_sizeに、false の場合は 0
  • scaledown_idletime : コンピュートノードのターミネート判定時に利用するアイドル時間

検証環境

  • AWS ParallelCluster 2.8.1
  • ジョブスケジューラー : Slurm
  • OS : Amazon Linux 2

スケールアウト処理の流れ

稼働中のクラスターにおいて、ノード数がASGの上限に達しておらず、ジョブのキューイングからノード追加が必要な場合の処理です。

新規クラスター作成時には、実質的に(2)以降の処理が動作しているはずです。

ノード追加命令の流れ

この節の処理は、ヘッドノードで動作する jobwatcher プロセスが行います。

(1)ジョブキューのポーリング

ジョブスケジューラーのジョブキューをポーリングし、ノード追加が必要かチェックします。

(2)ASGのサイズ変更

コンピュートノードが足りない場合、ASG::UpdateAutoScalingGroup API でASG のインスタンス数を増やします。

ノード追加の流れ

(3)新規EC2インスタンス追加

ASG が新規にEC2インスタンスを追加します。

(4)ブートストラップ処理

EC2インスタンスのブートストラップ処理が完了すると、/opt/parallelcluster/scripts/compute_ready が SQS に準備完了メッセージを送ります。

SQSメッセージ送信処理の流れ

この節の処理は、ヘッドノードで動作する sqswatcher プロセスが行います。

(5)SQSキューのポーリング

SQS の新規キューをポーリングします。

※ノードの追加・削除で同じSQSキュー・プログラムを利用します。

(6)新ノードをジョブスケジューラーに通知

ノード追加のメッセージだった場合、ジョブスケジューラーに追加します。

(7)DynamoDB に追加

ノード情報をDynamoDBに追加します。

スケールイン

稼働中のクラスターにおいて、ノード数がASGの下限に達しておらず、余剰ノードの削除が必要な場合の処理です。

ノード削除命令の流れ

この節の処理は、各コンピュートノードで動作する nodewatcher プロセスが行います。

(1)ジョブキューの確認

ジョブスケジューラーのジョブキューをポーリングします。

ノードがジョブを処理してておらず、保留中のジョブもなく、ノードが一定期間アイドル状態であり、ノード数がASGの下限に達していない場合、削除処理に入ります。

(2)ASGのサイズ変更

ASG::TerminateInstanceInAutoScalingGroup API で自ノードをターミネートするように命令します。

SQSメッセージの送信処理の流れ

(3)ASGのターミネートイベントをSNSに通知

ASG のスケーリングイベントはAmazon SNSに通知することができます。

この機能を利用し、EC2インスタンスのターミネートイベント(autoscaling: EC2_INSTANCE_TERMINATE)をAmazon SNSに通知します。

(4)SNSメッセージをSQSに通知

Amazon SNSのサブスクライブ機能を使い、SNS に送信したメッセージを SQS に配信します。

SQSメッセージの受信処理の流れ

この節の処理は、ヘッドノードで動作する sqswatcher プロセスが行います。

(5)SQSキューのポーリング

SQS の新規キューをポーリングします。

※ノードの追加・削除で同じSQSキュー・プログラムを利用します。

(6)破棄ノードをジョブスケジューラから削除通知

ノード削除のメッセージだった場合、ジョブスケジューラーから削除します。

(7)DynamoDB から削除

ノード情報をDynamoDBから削除します。

最後に

AWS ParallelClusterで従来のジョブスケジューラ (SGE、Slurm、Torque) を使用してクラスターを構築すると、ASGでクラスターが管理されます。 このASGのスケーリングの流れを確認しました。

ジョブキューに対して期待通りにスケーリングしない場合、処理の流れとヘッド・コンピュートノードの /var/log 以下のログを確認しましょう。

参考