もち256ログ
About Note Log
Log
published: 2022-04-10, modified: 2022-05-22
k8sクラスタによる並列処理のパフォーマンス検証【2】

■ 2022-05-22 追記

本記事の実験で使用されている計測ツールにネットワークの問題で1秒あたり500個のジョブしか処理ができない問題があることがわかりました。

そのため、今回と同様の実験の再検証を「k8sクラスタによる並列処理のパフォーマンス検証【3】」にて行いました。


以前、Raspberry Piで構築したk8sを使用し、ジョブの並列実行のパフォーマンス検証を行いました。

今回は、さらに2個のRaspberry Pi(以下「ラズパイ」と呼称)を手に入れたので、その2個をワーカーノードに追加し、色々実験を行いました。


また、前回の検証時に「2ワーカーノード、3並列以上でジョブをデプロイした場合、全てのPodが同時に起動しない」という問題が発生していました。

今回判明したことなのですが、この原因はどうやらクラスタのリソースの問題ではなく「ジョブを動かすノードでイメージがPullされていなかった」ことが問題でした。

そのため、今回は全てのワーカーノードでイメージがPullされている状態で、コンテナ起動の待機時間が発生しないように実験を行いました。


目的

今回の実験の目的は、下記のものになります。

  • 1マスターノード、4ワーカーノードのk8sクラスタでジョブの並列処理を行う場合、最適な並列実行数はいくつか
    (2ワーカーノードの場合、3並列がベストであったが、4ワーカーノードの場合も同様なのか気になった)
  • 上記で求めた並列実行数を1~4ワーカーノードで実行する場合、処理がどの程度変動するか
    (処理速度がワーカーノードに依存する場合、ワーカーノードが減るごとに処理時間が伸びるはず)

準備

今回の実験にて、下記のものを用意しました。


方法と結果と考察

0. 計測アプリについて

「準備」の項に記載した計測アプリですが、下記の仕様となっています。

アプリの仕様

前回の「アプリの仕様」の項と同じ仕様のため、説明を省きます。


計測区間について

処理速度の計測区間は、最初のクライアント実行時の「client_start」というログの出力時から、最後に素数の判定結果が出力される「[0-9]+_is(|_not)_prime」というログまでとします。

処理時間は、下記コマンドを実行してログから確認を行います。

kubectl get pods | grep -oP "indexed-job-\d+\S+"|xargs -I {} bash -c "kubectl logs {}"|sort|less

1. 最適な並列実行数の検証

実験方法

最初に、1マスターノード、4ワーカーノードの場合の最適な並列実行数の検証を行いました。

ワーカーノードが2機であった前回の実験では、3並列が最も効率が良いことがわかりました。
もし、ノードの数によって最適な並列数が変動するのであれば、3並列以上の場合の方が、処理速度が上がると考えたためです。

下記の手順で実験を行いました。

  1. APP_COUNT_MAXを50000に設定し、app-server.ymlをデプロイする
  2. 並列数(completions, parallelism)を任意の値に設定し、app-job.ymlをデプロイする
  3. "kubectl get pods"コマンドで、ジョブのコンテナが全て終了することを確認する
  4. "kubectl logs {{ ジョブのコンテナ名 }}"を実行し、クライアントのログを取得する
  5. 最初にクライアントが実行された時間から、最後にクライアントが実行された時間を記録する
  6. サーバ、ジョブのコンテナを全て終了する
  7. 同じ並列数を指定し、手順1~6を3回繰り返す
  8. 任意の並列数でそれぞれ3回データを取り、処理時間の平均値を求めたら、手順1~7までを繰り返す

実験結果

結果として、以下のようになりました。

並列数(個) 計測1回目(秒) 計測2回目(秒) 計測3回目(秒) 平均処理時間(秒)
1 368.020 371.808 368.164 369.331
2 196.069 196.914 195.652 196.212
3 136.980 136.879 136.252 136.704
4 117.754 117.224 117.224 117.401
5 99.807 105.468 106.356 103.877
6 102.868 102.518 99.891 101.759
7 95.128 97.882 93.547 95.519
8 101.232 83.086 101.289 95.202
9 102.032 100.891 102.890 101.938
10 103.599 96.229 93.651 97.826
11 98.144 99.164 95.946 97.751
12 100.321 93.978 101.138 98.479

結果を図示すると、以下のようになります。

blog_image

考察

  • 1マスター・4ワーカーノードで最適な並列数を求めたところ、3並列ではなく、5並列が最も処理効率が良いように見えた
  • 5並列以降、処理時間がほぼ100秒で推移していた
    これは、アムダールの法則による処理効率の限界だと思われる

2. 同じ並列数・異なるノード数による処理時間の変動の検証

実験方法

今回の「1. 最適な並列実行数の検証」によって、5並列が最もパフォーマンスが良いことがわかりました。

これを「ワーカーノード4機の場合の、最も良い並列数である(並列処理のパフォーマンスがノード数に依存している)」と仮定するのであれば、ワーカーノードが4機未満の場合、そのパフォーマンスが下がることを期待し、実験を行います。

今回はジョブが実行されるワーカーノードを1~3に制限し、素数判定の処理数(APP_COUNT_MAX)を500000まで設定し、5並列のジョブによって、処理終了までに何秒かかるかを計測します。


実験結果

結果として、以下のようになりました。

ノード数(個) 計測1回目(秒) 計測2回目(秒) 計測3回目(秒) 平均処理時間(秒)
1 159.999 160.501 160.158 160.219
2 107.200 108.943 107.964 108.036
3 107.814 107.450 108.077 107.780
4 99.807 105.468 106.356 103.877

結果を図示すると、以下のようになります。

blog_image

考察

  • 意外であったが、ノード数が2個以上の場合、測定結果に大きな差が生じないことがわかった
  • この実験結果からは「2個以上のラズパイのk8sクラスタでは、ノードを増やすことによる、ジョブの実行速度の上昇が見込めない」ということになる
  • また、前回の検証時「ワーカーノード2機の場合、3並列がベストである」という結論になったが、今回の結果によって否定されることになる
    (前回の検証時には「5並列で処理を行おうとすると、同時に3並列までしかコンテナが起動しない」という問題が発生していたが、これは冒頭にも記載したように、恐らくノードでイメージがPullされていなかったことが原因)
  • もしかしたら、計測アプリの仕様によって今回の結果が発生した可能性がある
    (サーバとジョブ実行のPodがHTTPによる通信を伴うため、ネットワーク内のパケットの配送が限界になっていたか、サーバの処理限界が100秒あたり50000アクセスまでであったか)

おわりに

今回の実験で、ワーカーノード4個の際に、最適な並列処理数を求めました。
しかし、実験結果ではワーカーノードが2個以上の場合、5並列でパフォーマンスがほぼ同一になってしまいました。

なので、次回に実験を行うとしたら、これがアムダールの法則の限界によるものなのか、実験ツールの方式によるものなのか、実験ツールや実験方法を変更して、原因を確かめてみようと思います。


今回は以上になります。

ここまで読んでいただき、ありがとうございました!



ログ一覧へ戻る