JMeterを利用した負荷テストでどのようにスレッド数、Ramp-Up期間、ループ回数をどうやって決めるか考える

what

前回の測定は、Ramp-Up期間がすべて 1 という極端なものであり、あまりよろしくないと聞いた。
そのため、再度、負荷テストを行う。
今回行いたい測定は、前回同様「サーバの負荷限界値」である。

負荷計測環境

前回とほぼ同じだが、負荷テスト対象のWebアプリケーションのバージョンが少々あがっている。

妥当なRamp-Up期間の決定について

JMeterで負荷テストするのはいいのだが、以下の数値をどのように決めるのに非常に悩む。

  • スレッド数
  • Ramp-Up期間
  • ループ回数


どうしたらよいものか、考えてみた。


itarchitect.jp

上記にテストシナリオ作成のヒントが書いてあるので読んでみた。「現実に即したテスト」という視点が非常に重要であると書いてある。
記事のヒット率の以下のようになる。

  • スレッド数が大きい場合は、Ramp-Up期間を「0」に設定すべきではない。(異常な状態が好ましくない 。現実に即したものだとは言えない。 ヒット率の初期値が異常に高くなってしまう。)
  • 「ヒット率の初期値を、できるだけヒット率の平均値に近い値に保つこと」が重要である。
  • Ramp-Up期間が大きすぎるのも問題である。(ピーク時の負荷が過小評価されてしまう可能性がある)


実は、これからテストを行おうとしているアプリケーションは本番で数年走っているものであり、「ヒット率の平均値」はログを見れば分かる。
それは、「10ヒット/秒」である。


しかし、今回の負荷テストは「限界値」を求めるため、スタート値を平均ヒット率の2倍の 「 20 」まで上げて、テストしてみようと思う。2倍と軽々しく上げる理由は前回スループットが160と出ているためである。


スレッド数が100で、ヒット率が20ヒット/秒と推定した場合、理想的なRamp-Up期間の推定値は、100÷20=5秒となる。

これで、以下のテストしてみようと思う。

負荷テスト

リクエス
名称 対象サーバ ポート番号 プロトコル メソッド パス その他(自動リダイレクト、リダイレクトに対応、!KeepAliveを有効にする、など)
リクエストA 192.168.0.5 80 http GET /a/bbb すべてOFF
リクエストB 192.168.0.5 80 http GET /a/ccc すべてOFF

今回は、2つのリクエストパターンを同時に走らせる。

スレッドプロパティ
回数 スレッド数(リクエスト数×スレッド数=スレッド数合計) Ramp-Up期間(秒)(スレッド数合計/ヒット率の平均値) ループ回数
1回目 600(2×600=1200) 60(1200÷20=60) 1
2回目 1200(2×1200=2400) 60(2400÷40=60) 1
3回目 1800(2×1800=3600) 60(3600÷60=60) 1
4回目 2400(2×2400=4800) 60(4800÷80=60) 1
5回目 3000(2×3000=6000) 60(6000÷100=60) 1
6回目 3300(2×3300=6600) 60(6600÷110=60) 1
7回目 3600(2×3600=7200) 60(7200÷120=60) 1
8回目 3900(2×3900=7800) 60(7800÷130=60) 1

上記のテストだと、ヒット率が期待するスループットになります。


実際には、以下のことも考慮してテストシナリオを作成することも重要であると書いてあるが、とりあえず無視してやってみる。

  • ユーザーの思考時間の考慮
  • レスポンス時間の要件定義
負荷計測結果
  • 1回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 600 19 17 26 9 87 0.0 10.007839474254833 1.3780325838573548
リクエストB 600 18 16 24 9 88 0.0 10.007338715057708 0.9870519631062779
合計 1200 19 16 25 9 88 0.0 20.008336807002916 2.364266360983743
  • 2回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 1200 20 18 26 9 110 0.0 20.010672358591247 2.755375783751334
リクエストB 1200 19 16 25 9 109 0.0 20.010672358591247 1.9737088947438632
合計 2400 19 17 25 9 110 0.0 40.0073346780243 4.727429195352482
  • 3回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 1800 22 20 32 9 243 0.0 30.009503009286274 4.132167894833364
リクエストB 1799 20 16 31 9 113 0.0 30.021360389827116 2.961091210324745
合計 3599 21 18 31 9 243 0.0 60.00233407245627 7.090445177431186
  • 4回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 2400 31 23 54 9 308 0.0 39.99600039996 5.507261773822617
リクエストB 2398 29 23 49 10 290 0.0 39.98932728546176 3.944259820148084
合計 4798 30 23 52 9 308 0.0 79.95867079958671 9.448892350348299
  • 5回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 3000 67 54 127 12 397 0.0 49.98417167896833 6.882586139389193
リクエストB 2998 65 54 123 11 316 0.0 49.96833227774259 4.928517148488283
合計 5998 66 54 125 11 397 0.0 99.9150438939881 11.807018196848295
  • 6回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 3300 1428 1376 2586 18 3267 0.0 52.55446553701108 7.236503555389222
リクエストB 3149 1422 1374 2558 12 3343 0.0 50.21928075911012 4.9532689029981665
合計 6449 1425 1375 2574 12 3343 0.0 102.70416613581348 12.182909571482035
  • 7回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 3600 3685 3792 5433 13 20998 0.0022222222222222222 52.6200394650296 7.382107359497185
リクエストB 3206 3689 3799 5439 38 21014 0.0028072364316905803 46.88162608759231 4.782921373473715
合計 6806 3687 3793 5435 13 21014 0.0024977960622979724 99.4811079441643 12.162931420375648
  • 8回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 3900 5324 5094 12047 21 25767 0.03 54.26011464188325 9.37258699009405
リクエストB 3332 5373 5094 13338 23 25651 0.028811524609843937 46.40539260744826 6.190907373750035
合計 7232 5347 5094 12759 21 25767 0.029452433628318585 100.61773053592297 15.55712050962769
負荷計測結果分析

結果 Throughput は おおよそ100 でした。
5回目の負荷テストまではスループットがそのまま素直に出ますが、6回目以降のテストでは、スループットは99〜102しか出ません。

このパターンのリクエストであれば、論理上1日8,640,000(100*60*60*24)リクエストさばけることになります。

Ramp-Up 0 でテスト

前回、Ramp-Up 1 で行ったが、それはよろしくないということで今回は Ramp-Upを 60 に設定して行ったのだが、ためしに Ramp-Up 0 で行ったらどうなるのか試してみた。

リクエス

同じ

スレッドプロパティ
回数 スレッド数(リクエスト数×スレッド数=スレッド数合計) Ramp-Up期間(秒) ループ回数
1回目 1(2×1=2) 0 1
2回目 200(2×200=400) 0 1
3回目 400(2×400=800) 0 1
4回目 600(2×600=1200) 0 1
5回目 1000(2×1000=2000) 0 1
6回目 1500(2×1500=3000) 0 1
7回目 2000(2×2000=4000) 0 1
Ramp-Up 0 の負荷テスト結果
  • 1回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 1 42 42 42 42 42 0.0 23.809523809523807 3.278459821428571
リクエストB 1 14 14 14 14 14 0.0 71.42857142857143 7.045200892857142
合計 2 28 42 42 14 42 0.0 34.48275862068965 4.074622844827586
  • 2回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 200 1051 1042 1744 51 2094 0.0 83.89261744966443 11.551620176174497
リクエストB 200 1802 1824 2049 435 2320 0.0 50.58168942842691 4.9890142893272635
合計 400 1426 1642 1970 51 2320 0.0 99.82530571499876 11.79576366358872
  • 3回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 400 2053 2014 3595 56 4274 0.0 83.55964069354502 11.505770837685398
リクエストB 400 3535 3696 4009 557 4282 0.0 51.092093498531106 5.039356878273088
合計 800 2794 3325 3925 56 4282 0.0 101.44559979710881 11.987224194775552
  • 4回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 600 3113 2922 5205 60 10961 0.0 51.484468851896345 7.089170027458383
リクエストB 600 5001 5099 5489 23 10917 0.0 51.65733964700818 5.095108695652174
合計 1200 4057 4771 5445 23 10961 0.0 102.75732145915396 12.14222255523206
  • 5回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 1000 7210 4856 14088 112 21821 0.0 43.757931125016405 6.025262000612611
リクエストB 1000 4548 4831 5413 23 21500 0.0 43.94059231918446 4.333984203357061
合計 2000 5879 4836 13073 23 21821 0.0 87.38967054094206 10.326318491654288
  • 6回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 1500 11069 8895 21344 115 21592 0.3006666666666667 65.80679126085812 32.170609590243046
リクエストB 1500 5094 3819 12269 16 21560 0.037333333333333336 56.56961834364157 8.128788985895309
合計 3000 8082 5078 21154 16 21592 0.169 112.62952395254543 35.62245996959003
  • 7回目
Label # Samples Average Median 90% Line Min Max Error % Throughput KB/sec
リクエストA 2000 12438 13891 21320 71 25594 0.373 70.33832735457551 40.32831513329113
リクエストB 2000 6536 5025 14052 296 25257 0.066 65.87398307038634 11.745125325252792
合計 4000 9487 5755 21234 71 25594 0.2195 131.43195110731418 49.39505364066505

2〜4回目はスループットが 100 近くを示しており、今回の結果に近い値が出ている。しかし、エラーが出始める6回目以降は、正しいレスポンスが帰ってこないため、スループットが高めになっています。では、エラーが 0% のところのスループットを参考にすればよいのかといえばそうでもなく、5回目はエラーが 0% にもかかわらずスループットは 87 と出ています。よって Ramp-Up 0 による計測は、Ramp-Upが 60 のときより、計測しにくいという結果になりました。とはいえ、100に近い数字が出ていますので、参考にならないわけではありませんね・・・。

まとめ

Ramp-Up 0 というのは計測しにくいという結果になった。ただ、瞬間的な負荷(ピーク時の負荷)が過小評価されるのもよろしくないので、完全に無視できるものでもない。

負荷テストのパターンは山のようにあるため、正解というのはないと思うが、実際そのサーバが現実にどのような負荷を想定するかが重要であると思った。その結果が利用者にとって一番意味のあるデータだからだ。


サーバの負荷のタイミング、流れについて整理すると以下のようになる。

サービスが動いているサービスのスループット取得

1. 現在のログを分析して、リクエスト状況の調査
2. その調査に基づき、負荷テストシナリオを作成する
3. (多くは本番環境ではできないとおもうのでデモ環境で)負荷テスト実行
4. 現在、どのくらいのスループットなのかが取得できる。

サービスリリース前のスループット取得

1. リクエスト状況の想定
2. その想定に基づき、負荷テストシナリオを作成する
3. 本番のサーバ環境で負荷テスト実行。
4. 現在、どのくらいのスループットなのかが取得できる。

スループット取得後

1. サーバ負荷(リクエスト/秒、ロードアベレージ、CPU、メモリ、I/Oなど)を監視する。
2. (sarなどを見て)負荷が高くなってきたら、サーバを改善してより多くの負荷に耐えられるようにする。(メモリ増強、I/O負荷軽減、スケールアウト、アプリケーションの改造など)。
3. 現在のログを分析して、リクエスト状況の把握。
4. 新しくなったサーバ性能、アプリケーション性能の環境(多くは本番環境ではできないとおもうのでデモ環境)で、負荷テスト実施。
5. 現在、どのくらいのスループットなのかが取得できる。



負荷テストについて、まだまだ分からないことだらけなので、突っ込みお願いします><