TT Lab
はじめる
学ぶ 学習パス コース

負荷テスト

試験の目標値はどこから来るのか

TT Labで続きを見る

目標

4週間分の時間別トラフィックデータに、1日の総量・ピークの時間帯・安全係数・障害への余裕・成長率を順に適用して、負荷テストの目標RPSを導き出し、その目標を実際にかけて、この環境で出せるかまで確認します。

なぜ重要なのか

負荷テストの計画書で、最もよく空欄になっているのは、目標RPSの出どころです。「1秒あたり1,000件」がどこから出たのかを尋ねると、たいてい答えがなく、それではテストに合格しても、何を保証したのかを言えません。目標は、運用データから導き出す必要があります。1日の総量を86400で割った平均は、ほとんどいつも実際のピークより何倍も小さく、その平均で容量を決めると、ちょうどその倍率の分だけ足りなくなります。そこに、ピークでも容量を使い切らないためのヘッドルーム、ゾーン1つが抜けても耐えるための余裕、次の計画の周期までの成長率が、順に掛け合わされます。最後に、そうして決めた目標が実際にかけられるかを、一度確認する必要があります。かけられなかった負荷で得た合格は、合格ではありません。

ステップ

  1. /opt/lab/lt/lt-capacity-target/traffic.tsvは、4週間分の時間別のリクエスト数です(ヘッダー1行のあと날짜 시각 요청수、プレースホルダーは日付、時刻、リクエスト数です)。日付ごとの合計を、/root/lt-capacity-target/daily.tsvに、タブで区切った2列<날짜> <하루 총 요청 수>で28行書き(プレースホルダーは日付と1日の総リクエスト数です)、/root/lt-capacity-target/01-peak-day.txtに、2行peak_date=とpeak_total=を書いてください。最も忙しかった1日です。
  2. 最も忙しかった日の24時間のうち、最も忙しい1時間を探して、/root/lt-capacity-target/02-peak-hour.txtに、3行peak_hour=(0..23の整数)・peak_hour_requests=(その1時間のリクエスト数)・peak_share=(その1時間がその日の総量に占める割合、小数第4位まで)を書いてください。
  3. /root/lt-capacity-target/03-rps.txtに3行を書いてください。avg_rps=は、最も忙しかった日の総量を86400で割った値、peak_rps=は、最も忙しい1時間のリクエスト数を3600で割った値(どちらも小数第2位まで)、peak_over_avg=は、2つの比(小数第2位まで)です。
  4. 運用の余裕(ヘッドルーム)を30%に取ります。ピークでも容量の70%だけを使うという意味です。/root/lt-capacity-target/04-headroom.txtに、2行headroom=0.30とrps_after_headroom=を書いてください。後ろの値は、peak_rps ÷ (1 − headroom)を小数第2位まで書きます。
  5. サービスは4つのゾーンに均等に配置されていて、1つのゾーンがまるごと抜けても、ピークを受け止める必要があります。/root/lt-capacity-target/05-nplus1.txtに、3行nodes=4・surviving=3・rps_after_nplus1=を書いてください。後ろの値は、rps_after_headroom × nodes ÷ survivingを小数第2位まで書きます。
  6. トラフィックが月8%ずつ増えていて、この容量で6か月を持ちこたえる必要があります。/root/lt-capacity-target/06-growth.txtに、4行monthly_growth=0.08・months=6・growth_factor=(1.08の6乗、小数第4位まで)・rps_after_growth=(rps_after_nplus1 × growth_factor、小数第2位まで)を書いてください。
  7. /root/lt-capacity-target/target.tsvを作成してください。ヘッダーなしで5行、各行はタブで区切った2列<단계> <RPS>です(プレースホルダーはステップ名とRPSです)。ステップ名は順にpeak・headroom・nplus1・growth・targetで、最初の4行は前のステップで書いた値を、最後のtargetの行は、rps_after_growthを切り上げた整数を書きます。そして/root/lt-capacity-target/07-note.txtに、2行test_target_rps=(その整数)とreason=(この目標がどこから出たかを60文字以上)を書いてください。
  8. /opt/lab/lt/lt-capacity-target/echo.pyをポート8095で起動し、ステップ7で決めた目標を、実際にかけてみてください。ワーカーは20個、ワーカーあたりのレート上限は올림(목표 ÷ 20)、リクエスト数は목표 × 5とし(プレースホルダーは切り上げと目標です)、元のCSVを/root/lt-capacity-target/run.csvに残します。そのあと/root/lt-capacity-target/08-run.txtに、5行target_rps=・workers=20・q_per_worker=・measured_rps=(run.csvから再計算した値、小数第2位)・reached=(measuredが目標の90%以上ならyes、そうでなければno)と、50文字以上のnote=を書いてください。

参考

まず1日の総量を数える

/opt/lab/lt/lt-capacity-target/traffic.tsvは、4週間分の時間別のリクエスト数です(ヘッダー1行のあと날짜 시각 요청수、プレースホルダーは日付、時刻、リクエスト数です)。日付ごとの合計を、/root/lt-capacity-target/daily.tsvに、タブで区切った2列<날짜> <하루 총 요청 수>で28行書き(プレースホルダーは日付と1日の総リクエスト数です)、/root/lt-capacity-target/01-peak-day.txtに、2行peak_date=とpeak_total=を書いてください。最も忙しかった1日です。

awk -F'\t'で、3列目を日付ごとに足せばよいのです。ヘッダーの1行は飛ばしてください。容量計画の基準は平均ではなく、最も忙しかった日です。平均で決めると、その日に崩れます。

その1日の中で、いつが最も忙しかったか

最も忙しかった日の24時間のうち、最も忙しい1時間を探して、/root/lt-capacity-target/02-peak-hour.txtに、3行peak_hour=(0..23の整数)・peak_hour_requests=(その1時間のリクエスト数)・peak_share=(その1時間がその日の総量に占める割合、小数第4位まで)を書いてください。

24時間が均等なら、1時間の取り分は1 ÷ 24 = 0.0417です。実際の値がその何倍かが、このステップの要点です。その倍率が、そのまま「平均で計画するとどれだけ足りないか」です。

平均で割った値は、何倍足りないか

/root/lt-capacity-target/03-rps.txtに3行を書いてください。avg_rps=は、最も忙しかった日の総量を86400で割った値、peak_rps=は、最も忙しい1時間のリクエスト数を3600で割った値(どちらも小数第2位まで)、peak_over_avg=は、2つの比(小数第2位まで)です。

1日の総量 ÷ 86400は、「その日が24時間ずっと同じように忙しかったなら」の値です。実際のピークは、それよりはるかに大きいのです。この倍率を知らずに、平均で容量を決めると、ピークの時間帯に、ちょうどこの倍率の分だけ足りません。

余裕を残して、目標を上げる

運用の余裕(ヘッドルーム)を30%に取ります。ピークでも容量の70%だけを使うという意味です。/root/lt-capacity-target/04-headroom.txtに、2行headroom=0.30とrps_after_headroom=を書いてください。後ろの値は、peak_rps ÷ (1 − headroom)を小数第2位まで書きます。

ピークで容量を100%使うと、キューがたまり始める地点に、すでに乗っていることになります。待ち行列理論では、利用率が1に近づくほど、待ち時間が急激に増えます。そのため、目標はピークより上に取ります。割り算です。0.7を掛けるのではありません。

1つのゾーンが抜けても耐えられるようにする

サービスは4つのゾーンに均等に配置されていて、1つのゾーンがまるごと抜けても、ピークを受け止める必要があります。/root/lt-capacity-target/05-nplus1.txtに、3行nodes=4・surviving=3・rps_after_nplus1=を書いてください。後ろの値は、rps_after_headroom × nodes ÷ survivingを小数第2位まで書きます。

4つのゾーンが3つだけ残っても、同じ負荷を受けるには、全体が4/3倍の容量を持っている必要があります。そのため、テストで確認すべき負荷も、その分だけ上がります。この係数を抜かすと、平常時は問題なく、ゾーン1つが抜ける日にだけ崩れます。最も悪い失敗の仕方です。

半年後にも使える目標か

トラフィックが月8%ずつ増えていて、この容量で6か月を持ちこたえる必要があります。/root/lt-capacity-target/06-growth.txtに、4行monthly_growth=0.08・months=6・growth_factor=(1.08の6乗、小数第4位まで)・rps_after_growth=(rps_after_nplus1 × growth_factor、小数第2位まで)を書いてください。

複利です。8% × 6 = 48%ではなく、1.08の6乗です。2つの差が、目標の数値を何パーセント変えるかを、自分で計算してみてください。成長率はデータから推定するのが原則ですが、このステップでは、製品計画から受け取った値のままにして、計算方法に集中します。

目標がどこから出たかを、1つのファイルに残す

/root/lt-capacity-target/target.tsvを作成してください。ヘッダーなしで5行、各行はタブで区切った2列<단계> <RPS>です(プレースホルダーはステップ名とRPSです)。ステップ名は順にpeak・headroom・nplus1・growth・targetで、最初の4行は前のステップで書いた値を、最後のtargetの行は、rps_after_growthを切り上げた整数を書きます。そして/root/lt-capacity-target/07-note.txtに、2行test_target_rps=(その整数)とreason=(この目標がどこから出たかを60文字以上)を書いてください。

この表1枚が、「1秒あたり1,000件はどこから出たのですか」という質問への答えです。4行を見れば、どの仮定を変えると目標がどれだけ動くかも、ひと目でわかります。ヘッドルームを20%に下げると、目標がいくつになるかを、頭の中で計算してみてください。

その目標は、この環境でかけられるのか

/opt/lab/lt/lt-capacity-target/echo.pyをポート8095で起動し、ステップ7で決めた目標を、実際にかけてみてください。ワーカーは20個、ワーカーあたりのレート上限は올림(목표 ÷ 20)、リクエスト数は목표 × 5とし(プレースホルダーは切り上げと目標です)、元のCSVを/root/lt-capacity-target/run.csvに残します。そのあと/root/lt-capacity-target/08-run.txtに、5行target_rps=・workers=20・q_per_worker=・measured_rps=(run.csvから再計算した値、小数第2位)・reached=(measuredが目標の90%以上ならyes、そうでなければno)と、50文字以上のnote=を書いてください。

総RPSは、요청 수 ÷ (max(offset + response-time) − min(offset))です(プレースホルダーはリクエスト数です)。目標をかけられなかったなら、それはサーバーの結論ではなく、負荷ジェネレーターの限界で、レポートにその事実を書く必要があります。書かないと、次の人がこの数字を、サーバーの能力として読みます。