KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

JMeter の利用方法(1) – Ramp-up、スレッド数、ループ回数の誤用

LINEで送る
Pocket

こんにちは、今回から何回かに分けて Apache JMeter の使い方について記事を書いてみたいと思います。

単純に負荷を限界までかけるだけのテストを行う場合、AB(Apache Bench) 等の簡易なツールから行う方法から、JMeter のように GUI のツールを備えたシナリオテストまで可能なツールで行う方法までさまざまな方法があります。

実務では特定の URL だけをひたすら叩いて・・というテストではあまり意味のある数字が出て来ない事が多く、JMeter を利用してシナリオを作ってテストする事が多いです。

限界まで負荷をかけ続けるのではなくて、秒間リクエスト数(rps)を決め打ちして実行してみてサーバ側の負荷やその他の状態を監視したいというニーズもすぐに出てきます。

さて、JMeter でそのようなテストを実施する場合にどのように行うかというと、これにはいくつかの方法が考えられるのですが、どうにも日本では奇妙な方法がスタンダードになっているような気がしますので、この問題について今回は書きました。

それは秒間リクエスト数の固定に Ramp-up、スレッド数、ループ回数を指定する方法です。

これは結構広く利用されている方法のようで、確かに用を足します。どのようにしてスループットを指定するかと言うと、ループ回数を1回に指定して、Ramp-up 期間とスレッド数を同じに指定して動きを見て頂くのが一番理解しやすいと思います。

サンプラが一個しかない前提で以下をすべて記述しますが、設定内容はこのようになります。

スレッド数: 60
Ramp-Up期間(秒): 60
ループ回数: 1 (無限ループのチェックボックスはオフにしてください)

この設定の意味は、

「60のスレッドを60秒の時間をかけて処理開始し、スレッド毎にシナリオを一回だけ実行する」

です。JMeter は平均的に処理開始のタイミングをばらして実行してくれるので、毎秒1回ずつ処理が実行され、1rps の負荷をかけることができることになります。このテストは 60 秒で終了することになります。

では、10 rps で実行してみましょう。

図3

この場合の実行結果は、以下のようになります。

図4

統計レポートを見ると、Throughput のところで、10.0/sec となっており、確かに 10rps がテストできたことがわかります。(上記スナップショットでは偶然コンマ以下まで綺麗にそろってますが、このくらい短いテストだとコンマ以下はゼロにならない事も多いです)

このテスト方法の何が問題かというと、この指定方法では耐久テストができない事です。

「10 bps で 60 秒のテストができたのだから、1時間ならその 60 倍にして設定してやるだけでしょ??」

と思われると思うのですが、

スレッド数: 36000
Ramp-Up期間(秒): 3600
ループ回数: 1

ではおそらくほとんどの環境でテストはうまく動かないでしょう。(実際に試してみていただくと JMeter は CPU を食いきって動かなくなると思います)

同じ 10rps の負荷をかけるとしても、

スレッド数: 3600
Ramp-Up期間(秒): 3600
ループ回数: 10

であれば大体の環境でうまくいくと思います。これはどういう事かというと、

JMeter は、Ramp-up の設定によらず、指定されたスレッド数分だけのスレッドをテストの最初にクリエイトする

からです。そのため、実行開始時間はどのようにずれたとしてもテスト開始時に一気に三万個ものスレッドが起動されることになります。メモリも一気に確保されますし、起動後に大量発生するCPUのコンテキストスイッチだけでCPUは食いつぶされてしまうことになります。

JMeter のドキュメントを見ると、

The ramp-up period tells JMeter how long to take to “ramp-up” to the full
number of threads chosen. If 10 threads are used, and the ramp-up period
is 100 seconds, then JMeter will take 100 seconds to get all 10 threads up
and running. Each thread will start 10 (100/10) seconds after the previous
thread was begun.

「スレッドのスタートと実行をずらすのが ramp-up の指定である」

と書かれており、この動作はバグに見えます。いずれにせよこのような実装である以上、(ある程度はループ回数を多く指定できることで緩和できるとはいえ)秒間スループットの指定方法としてこの機能を利用するのは耐久テストの事まで考えると無理があります。
・・・というのがバージョン2.8以前までの状況だったのですが、バージョン2.8になって、「Delay Thread creation until needed」というオプションが追加されました。

図5

JMeter のドキュメントの記載は以下です。

JMeter versions since 2.8 have an option to delay thread creation until
the thread starts sampling, i.e. after any thread group delay and the
ramp-up time for the thread itself. This allows for a very large total
number of threads, provided that not too many are active concurrently.

このチェックを入れると、スクリーンショットのように、

「10時間にわたって360万のスレッドを起動してテストを実施」

というような、今まで実行した瞬間に CPU 利用率が 100 % に張り付いてしまうようなテストも実施が可能になります。

しかし、この方法によっても何かの拍子にサーバ側でもクライアント側でもよいのですがさばける処理量に変化が発生してしまうとあっという間にクライアント側のスレッドがたまってしまい、テストがストップしてしまう事になります。

サーバ側が落ちるのは負荷テストをやっているんだからまあ全然いいのですが、クライアント(JMeter)がこんなに簡単にストップしてしまうのは問題でしょう。

もう一つの問題はこの方法を取った場合の JMeter 側の処理限界の低さです。サーバ側は 1000 rps をさばけるサービスに対して手元のマシンでは 150 rps 程度が限界で、それ以上の数字を指定するとあっという間にスレッドがたまってしまいテストがストップしてしまいました。シナリオを実行する都度スレッドを起動しているのですからこれはかなり効率が悪い処理です。限界が低くなって当然でしょう。

ループ回数の方を多目に指定してやる事で解決するとはいえ、こんなことまで考慮してたらかえって話が難しくなってしまっているような気がするのは私だけでしょうか?

そもそも Ramp-up は JMeter のマニュアルには

Ramp-up needs to be long enough to avoid too large a work-load at the start
of a test, and short enough that the last threads start running before the
first ones finish (unless one wants that to happen).

「Ramp-up は(同時にリクエストが流れることによる)テスト開始時の過剰な負荷を避けることができるように設定する必要がある」

とあるのですから設計意図を汲んだ利用方法がよいでしょう。
という事で、長くなってしまいましたが私のおすすめのスループット制限方法は

・定数スループットタイマー
・スループットシェイピングタイマー(Throughput Shaping Timer)

のいずれかを利用する方法です。

次回以降これらのタイマーの利用方法を記事にしたいと思います。特に、プラグインが必要なためか「スループットシェイピングタイマー」は非常に有用なのにも関わらず利用方法を説明している日本語サイトが見当たらなかったので、気合を入れて紹介したいと思います!

この記事に関するご意見、ご感想、ご質問、お待ちしています!

よろしくお願いします。

 

【関連記事】
JMeter の利用方法(1) – Ramp-up、スレッド数、ループ回数の誤用
JMeter の利用方法(2) – テスト結果の確認方法
JMeter の利用方法(3) – 負荷テスト中に何を監視するのか?
JMeter の利用方法(4) – タイマによるスループットの制限方法

Performance Testing With Jmeter 2.9
JMeter バージョン 2.10 について
JMeter バージョン 2.11 について

 

LINEで送る
Pocket