Out Of My Memory

雨垂れ石を穿つ

【Jmeter】スレッドグループのスレッド数・RampUp・ループ回数について

要約

  • スレッド数:仮想ユーザの数を設定する。10に設定すれば10ユーザで負荷掛けを行うと考えればよい
    • 負荷調整はスレッド数だけでなく、リクエスト間隔で行う
  • RampUp:仮想ユーザが全員立ち上がるまでの時間を設定する
    • 負荷をばらつかせるためRampUpは設定した方がいい
  • ループ回数:1つのスレッドが何回ループするかを設定する
    • 負荷掛け時間はループ回数ではなく、Durationで調節した方がいい

使用資材・環境など

スレッド数(これの説明が大半)

仮想ユーザの数を設定する箇所。ここの数値を10とすれば、10ユーザで負荷掛けを行うと考えればいい。
スレッド数によって、生成できる負荷量の上限は大きく変わるが、サーバのレスポンスタイムによっては、1スレッドで10TPSを出すことができるし、逆に10スレッドで5TPSさえ出すことができない場合がある。
Jmeter側でリクエスト間隔を調節すれば、100スレッドで1TPSしか出さないようにもできる。
リクエスト間隔を調節すれば、多くのスレッドで少ないTPSを出せるが、少ないスレッドでは大きなTPSを出すことは基本難しい。(レスポンスタイムが爆速であれば可能)

具体例的な

以下の具体例で、狙ったTPSを出すにはレスポンスタイムに応じてスレッド数を調整しなければいけないことを体感してもらえればうれしいです。理解してもらえれば、10TPSの負荷をかけたいから10スレッドでいいなどとは考えないようになるでしょう。

以下の様にShell Bean Sampler1つの負荷シナリオを使用します。
1秒スリープして終了するだけ。統計レポートには1秒後にレスポンスタイムが返却されたような挙動になります。
sleepを50ミリ秒に設定すれば50ミリ秒でレスポンスが返却されてたように統計レポートに表示されます。

f:id:pzdl-HIRAKU:20191222211509p:plain
使用する負荷シナリオ

1スレッド1ループで単発実行すると統計レポートには1秒でレスポンスが返却されたように見える。
ThroughtPutは59.9/minとほぼ1TPS出ていることがわかる。

f:id:pzdl-HIRAKU:20191222211712p:plain
1スレッド1ループでの実行結果

100スレッドで10TPSを狙ってみる。負荷掛け時間は1分とする。
リクエスト間隔を調節しなければ100TPS出てしまうので定数スループットタイマーでリクエスト間隔を調節する。

f:id:pzdl-HIRAKU:20191222212346p:plainf:id:pzdl-HIRAKU:20191222212401p:plain
100スレッドで10TPSを狙う

定数スループットタイマーについては以下の記事を参照してください 【Jmeter】負荷量を調整する方法 - Out Of Memory

確かに100スレッドでも10TPSを出すことができた。

f:id:pzdl-HIRAKU:20191222212653p:plain
100threadで10TPS 負荷試験結果

次に、Shell Bean Samplerのsleepを50ミリ秒にして1スレッドで10TPSを狙ってみる。 シナリオの構成は全く一緒。変更点はShell Bean Samplerのsleepが50になっていること、スレッドグループのスレッド数が1になっていること。

f:id:pzdl-HIRAKU:20191222213053p:plainf:id:pzdl-HIRAKU:20191222213059p:plainf:id:pzdl-HIRAKU:20191222213102p:plain
1スレッドで10TPSを狙う

レスポンスタイムが50ミリ秒程度となっているため1スレッドでも10TPSを出すことができた。

f:id:pzdl-HIRAKU:20191222214202p:plain
1スレッドで10TPS 負荷試験結果

次にShell Bean Samplerのsleepを1秒にし、1スレッドで10TPSを狙ってみる。(もちろん無理)

f:id:pzdl-HIRAKU:20191222214840p:plain
1スレッドで10TPS 負荷試験結果(無理)

レスポンスタイムが1秒の時点で1スレッドでは1TPS以上出すことは不可能。
なぜスレッド数の説明をここまでしているかというと私がこれで嵌ったからです。。。

RampUp

設定したスレッド数をすべて立ち上げるまでの時間を設定する。
ここを0秒にすると、負荷試験開始と同時にすべてのスレッドを立ち上げる。
ここを設定する意義は各スレッドが送るリクエストをばらつかせるという理由がある。

以下の様にHTTPリクエストをA→B→C→Dと送る負荷シナリオがあったとする。

f:id:pzdl-HIRAKU:20191222204401p:plain
簡単な架空の負荷シナリオ

RampUpを0秒にした場合、以下の様な負荷挙動になることがある。

設定したスレッドみんなが一斉に立ち上がり、ほぼ同じタイミングでAリクエストを投げる。
↓
サーバが処理をしてレスポンスを返却(受信したリクエストをすべて捌いたとする)
↓
設定したスレッドみんながほぼ同じタイミングでレスポンスを受け取り、一気にBリクエストを投げる。
↓
サーバが処理をしてレスポンスを返却
↓
(略)

理想は、あるスレッドはAのリクエストを送信しており、ほかのスレッドはBとかCのリクエストを送信しているといったように各スレッドが送信するリクエストにばらつきがあることだ。
各スレッドが同時に同じリクエストを送信するより、各スレッドが違うリクエストを送っていた方が実際の負荷挙動っぽいしそれを再現するためにRampUpを設定する。

負荷シナリオを1周するのに1分もかからなければRampUpは1分とか5分とかでよいが、負荷シナリオの1周が長く、5分とかかかるのであればRampUp時間も10分や15分と長めに設定して送るリクエストをばらつかせるといい。

RampUpを設定するその他の理由としては、徐々にスレッドを起動した方がJmeter側の負荷が一気に上がって詰まることがないことが挙げられる。

ループ回数

スレッドグループの各スレッドが何回ループするかを設定する箇所。
例えばスレッド数が10でループ回数が5回なら10×5=50回のリクエストを送ることになる。

ただ、負荷試験を行うとなると10分間50TPSの負荷をかけ続け、サーバが目標とするスループットを出せており、かつ目標とするレスポンスタイム内にレスポンスを返せるか等の見るため、ループ回数で何回リクエストを送るかを設定するよりもどれくらいの時間負荷をかけ続けるかを設定した方が楽ちん。 もし、10分間50TPSをかけ続けたいなら、ループ回数は無限に設定し、持続時間を10分に設定するのが吉。
そしてかける負荷量(ここでは50TPS)はThink Time か 定数スループットタイマーで調整する。

f:id:pzdl-HIRAKU:20191222203716p:plain
10分間負荷掛けを行いたい場合の設定