【図解】Webシステムの性能試験とは?負荷試験・性能限界・ボトルネックを解説

はじめに

性能設計では、Response Time、Throughput、CPU、Memory、I/O、Network、Thread、Connectionなどについて目標値や設計値を決めます。

しかし、設計しただけでは、そのシステムが本当に想定した負荷を処理できるかは分かりません。そこで必要になるのが性能試験です。

性能試験の目的は、単に「最大何TPSまで処理できるか」を測定することではありません。本番で想定されるWorkloadを再現し、Response Time、Throughput、Error Rate、Resource使用率などが性能要件を満たしているかを確認します。

さらに負荷を段階的に増加させることで、どこでResourceやQueueが飽和し、どこからResponse TimeやError Rateが悪化するのかを確認できます。

性能試験では「結果の数値」だけを見るのではなく、どのようなWorkloadを与え、そのときシステム内部で何が起きていたのかを合わせて確認することが重要です。

Webシステムの性能試験とは

性能試験では、制御したWorkloadをシステムに与え、そのときのPerformanceを測定します。

項目確認内容
Response TimeRequestが完了するまでの時間
Throughput単位時間あたりに処理できたRequestやTransaction
Error RateRequestのうちErrorとなった割合
Resource使用率CPU、Memory、I/O、Networkなど
SaturationQueueやThread、Connectionなどの飽和
性能限界負荷の増加に対して、要求されたResponse Time・Throughput・Error Rateなどを維持できなくなる負荷領域

性能試験で重要なのは、「どれだけ速いか」だけではありません。たとえば1,200 TPSを処理できたとしても、Response Timeが5秒、Error Rateが3%であれば、性能要件を満たしているとはいえません。

また、性能試験の結果はWorkloadに依存します。同じ1,000 TPSでも、参照中心の処理とDB更新を伴う処理では、システムに与える負荷は大きく異なります。そのため、まず「何を試験するのか」を明確にする必要があります。

性能要件と合格基準

性能試験を実施する前に、合格基準を決めます。

通常負荷:800 TPS
ピーク負荷:1,200 TPS
Response Time:p95 < 500 ms
Response Time:p99 < 1,000 ms
Error Rate:0.1%未満
CPU使用率:設計上の上限値以内

ここで重要なのは、Throughputだけを合格基準にしないことです。Throughputを満たしていても、Response Time、Error Rate、CPU、Memory、I/O、Network、Thread、Connection、Queueなどが許容範囲を超えている可能性があります。

Resource使用率の基準は一律に決められるものではありません。「CPU 70%以下」のような値は例であり、実際にはシステム構成、冗長化方式、ピーク時の余力、縮退時の必要容量などを考慮して決めます。

性能試験の種類

性能試験では、確認したい目的に応じて負荷の与え方や試験時間を変えます。代表的な試験には、通常負荷を確認するLoad Test、ピーク負荷を確認するPeak Test、性能限界を確認するStress Test、長時間運転を確認するSoak Testなどがあります。

試験主な目的
負荷試験(Load Test)想定する通常負荷で性能要件を満たすか確認する
ピーク負荷試験(Peak Test)想定するピーク負荷で性能要件を満たすか確認する
ストレス試験(Stress Test)負荷を増加させ、性能限界や過負荷時の挙動を確認する
スパイク試験(Spike Test)急激な負荷増加に対する挙動を確認する
長時間試験(Soak Test)長時間運転によるResource増加や性能劣化を確認する
障害・縮退時試験Node停止やFailover時にも必要な性能を維持できるか確認する

本記事では、これらを単独の試験として分けるだけではなく、Webシステムの性能特性を確認するための一連の性能試験として扱います。

Workload Modelを設計する

性能試験で特に重要なのがWorkload Modelです。Workloadとは、システムに与えられる仕事や負荷のことです。

本番環境が存在する場合は、可能な限り本番のWorkloadを計測し、その特性を性能試験に反映します。

項目例
Request数1,000 RPS
参照・更新比率参照80%、更新20%
API・画面の割合API-A 50%、API-B 30%、API-C 20%
Request Size1 KB
Response Size10 KB
SessionLogin済みSessionを使用
Think Time操作間隔5秒
データ量本番相当
接続数5,000 Connection
時間変動通常、ピーク、バースト

単に「1,000 TPSを発生させる」だけでは、本番のWorkloadを再現したことにはなりません。本番で複数のAPIや画面が使われている場合は、それぞれの利用割合や処理特性も反映します。

平均値だけでWorkloadを考えない

Workloadには時間的なばらつきがあります。たとえば本番環境を1時間平均で見ると800 TPSでも、実際には通常500 TPS、ピーク1,200 TPS、一時的なバースト1,800 TPSという変化があるかもしれません。

平均800 TPSだけを再現する試験では、一時的なピークやバーストによって発生する問題を見逃す可能性があります。

処理の種類についても同様です。平均ではRead 90%、Write 10%でも、Writeが一定間隔でまとめて発生している場合、Storage I/OやQueueに一時的な負荷が集中することがあります。

負荷の与え方

Workload Modelを決めたら、どのように負荷を発生させるかを設計します。代表的な方法として、一定のRequest Rateを与える方法と、一定のConcurrent Usersを動作させる方法があります。

一定のRequest Rate

たとえば1,000 RPSのように、単位時間あたりのRequest数を基準に負荷を発生させます。外部から一定のペースでRequestが到着するシステムを再現するときに使いやすい方法です。

一定のConcurrent Users

1,000 Usersのように、一定数のUserがRequestを送信し、Responseを受け取ったあと、必要に応じてThink Timeを挟んで次のRequestを送信する方法です。

この方式ではResponse Timeが長くなると、1 Userあたりが単位時間に送信できるRequest数も減少します。その結果、システムの性能が低下するとRequest Rateも低下する場合があります。

そのため、性能限界を調べる場合は、設定したConcurrent Usersだけでなく、実際に発生したRPSやTPSも合わせて確認することが重要です。

負荷を段階的に増加させる

性能限界を確認する場合、最初から最大負荷を与えるのではなく、負荷を段階的に増加させます。これにより、どの負荷レベルからResponse TimeやError Rateが悪化し、ResourceやQueueが飽和し始めるのかを確認できます。

各段階で一定時間負荷を維持し、Response Time、Throughput、Error Rate、Resource、Queueなどを観測します。

投入負荷を増やしてもThroughputがほとんど増えず、Response TimeやError Rateだけが急増するようになれば、システムが性能限界に近づいている可能性があります。

Response Timeを評価する

Response Timeは平均値だけで評価しないことが重要です。

指標意味
Average平均Response Time
Median / p5050%のRequestがこの値以下
p9090%のRequestがこの値以下
p9595%のRequestがこの値以下
p9999%のRequestがこの値以下
Max最大Response Time

本番では一部のRequestだけが極端に遅くなることがあります。そのため、平均値だけではなくPercentileや分布を確認します。

Throughputを評価する

Throughputは、単位時間あたりに処理できた仕事量を表します。WebシステムではRPS(Requests Per Second)やTPS(Transactions Per Second)などを使います。

TPSのTransactionが何を意味するかはシステムによって異なるため、何を1 Transactionと数えるのかを明確にします。

また、性能試験では「投入した負荷」と「実際に処理できたThroughput」を分けて確認します。システムが飽和すると、投入負荷を増加させてもThroughputはほとんど増えず、Response TimeやError Rateだけが増加する場合があります。

ResourceとSaturationを同時に確認する

性能試験では、Load Generatorの結果だけでなく、試験中のシステム内部の状態も観測します。

Resource使用率だけでなく、処理待ちが発生していないかも確認します。CPU、Thread、ConnectionなどのResourceが処理能力の限界に近づき、Queueや待ち時間が増加している状態をSaturationとして観測します。

レイヤー主な確認項目
NetworkThroughput、Packet Loss、Retransmission、Connection
Web ServerConnection、Worker、Queue、KeepAlive
TomcatThread、Connection、Queue、Request処理時間
JVMHeap、GC、GC Pause、Allocation
DatabaseCPU、I/O、Connection、Wait、Lock、SQL Response Time
LinuxCPU、Memory、I/O、Network、Resource Limit
仮想化基盤CPU Ready、Memory、Storage Latency、Network

性能試験中にこれらを観測することで、試験が意図した負荷を発生させているか、どのResourceや制約が性能限界に関係しているかを確認できます。

Bottleneckを確認する

負荷を段階的に増加させると、どこかのResourceやQueueが先に限界に近づきます。

別のシステムでは、DB I/OやStorage Latency、External APIなどが先に性能限界となる場合もあります。

性能試験では、Load、Response Time、Throughput、Resource、Saturation、Thread、Connection、Queue、Database、External APIなどの関係を確認します。

Load Generator自身を確認する

性能試験では、試験対象システムに大量のRequestを送信して負荷を発生させます。

このとき、性能試験ツールを実行してRequestを発生させる側のサーバをLoad Generator(負荷生成サーバ)と呼びます。たとえば、JMeterやk6などのツールをLoad Generator上で実行し、Webシステムへ大量のRequestを送信します。

性能試験では、試験対象システムだけでなく、Load Generator自身に十分な処理能力があるかにも注意が必要です。

たとえば、1,500 RPSの負荷を発生させようとしても、Load GeneratorのCPUやNetworkが先に飽和すると、実際には1,000 RPSしか送信できない場合があります。

この状態で「Webシステムの性能限界は1,000 RPS」と判断すると、誤った評価になります。Webシステムではなく、Load Generator側がBottleneckになっているためです。

そのため性能試験では、Load GeneratorについてもCPU、Memory、Network、Connection、実際のRequest送信数、Errorなどを監視します。

特に、設定した負荷と実際に送信できたRequest Rateが一致しているかを確認することが重要です。

Errorを必ず確認する

ベンチマークツールが結果を出しているからといって、正常に処理できているとは限りません。

1,000 Request送信

200 OK      700
500 Error   200
Timeout     100

特にTimeoutやRetryが発生すると、利用者の操作数と実際にシステムへ到達したRequest数が一致しなくなることがあります。そのため、Request数、成功数、Error数、Timeout数、Retry数を確認します。

過負荷試験

Rate Limit、Queue上限、Timeout、Retry、Exponential Backoff、Jitter、Circuit Breaker、Load Sheddingなどが想定どおりに動作するかを確認します。

また、負荷を下げたあとにQueueやResponse Timeが低下し、正常状態へ戻れることも重要です。過負荷に耐えるだけではなく、過負荷から回復できることまで確認します。

障害・縮退時の性能試験

通常時だけではなく、障害や縮退状態でも必要な性能を維持できるか確認します。

たとえば4台構成のApplication Serverから1台が停止し、総負荷が変わらず残り3台へ均等に分散されると仮定すると、1台あたりの負荷は4÷3で通常時の約1.33倍になります。

Web / AP Node停止、DB Failover、Network経路障害、Backend遅延、External API遅延、Node復旧などを想定し、縮退時のResponse Time、Throughput、Error Rate、Resource使用率を確認します。

長時間試験

短時間の性能試験では発見できない問題もあります。Memory Leak、Connection Leak、File Descriptor Leak、Heap増加、GC増加、Thread増加、DB Connection増加、Cache肥大化、Disk使用量増加などです。

そのため、一定のWorkloadを長時間継続し、Resourceが時間とともに増加し続けていないか、性能が徐々に劣化していないかを確認します。試験時間は一律ではなく、システムの利用特性や発見したい問題に応じて決めます。

試験環境が本番を再現できているか確認する

性能試験の結果は試験環境にも大きく依存します。Server Spec、Node数、Network帯域、Network Latency、Database Size、Middleware設定、Kernel Parameter、Cache、External Systemなどが本番と大きく異なれば、試験結果にも影響します。

完全に本番と同じ環境を用意できない場合でも、何が同じなのか、何が違うのか、その違いが結果にどう影響する可能性があるのかを整理しておくことが重要です。

Warm-upとCacheの影響

性能試験では、試験開始直後と一定時間経過後で性能が異なる場合があります。Cache、JVMのJIT、Connection確立などの影響があるためです。

安定状態の性能を測定するときは、Warm-up後の測定区間を明確にします。一方、本番でServer再起動、Cache消失、Node追加、Failoverなどが発生するのであれば、Cold状態や復旧直後の性能も別途確認します。

性能試験結果を評価する

性能試験が終わったら、設計値と実測値を比較します。

項目設計値実測値
Throughput1,000 TPS1,080 TPS
p95500 ms未満420 ms
p991,000 ms未満850 ms
Error Rate0.1%未満0.02%
CPU設計上限70%63%

ただし、OK / NGだけで終わらせないことが重要です。性能要件を満たしていても、性能限界までの余力が小さければ、将来の負荷増加や縮退時に問題になる可能性があります。

そのため、性能要件を満たしたかだけではなく、性能限界までどれくらい余力があるかも合わせて評価します。

性能試験でよくある失敗

性能試験では、試験条件や測定方法が適切でないと、実際のシステム性能とは異なる結果を得ることがあります。代表的な失敗を整理すると、次のようになります。

よくある失敗問題
平均Response Timeだけを見る一部の遅いRequestを見逃す。p95、p99、Max、分布も確認する
平均Workloadだけを再現する本番のPeakやBurstを再現できない
単一APIだけで試験する本番の処理割合やResource競合を再現できない
データ量が本番と大きく異なるCache Hit率、Index、I/O特性などが本番と変わる
Load Generatorの限界を見逃す負荷生成側の限界をWebシステムの性能限界と誤認する
Errorを無視するThroughputが高くても正常処理できていない可能性がある
Warm Cacheだけで測定するCold StartやFailover直後の性能を評価できない
Retryを考慮しない利用者の操作数より実際のRequest数が増える場合がある
通常構成だけで試験するNode停止やFailoverなどの縮退時性能が分からない
システム内部を観測しないResponse TimeやThroughputが悪化した原因を特定できない

性能試験の進め方

重要なのは「負荷をかける → 結果を見る」だけで終わらないことです。試験の目的に応じてWorkloadと負荷シナリオを設計し、どのようなWorkloadを与えたか、どのようなPerformanceになったか、システム内部で何が起きたかを関連付けて評価します。

まとめ

Webシステムの性能試験では、最大Throughputだけを測定するのではなく、本番で想定されるWorkloadに対して性能要件を満たせるかを確認します。

そのためには、本番のWorkload特性を把握し、Request Rate、処理の種類と割合、データ量、Request / Response Size、Concurrent Users、時間変動、ピーク、バーストなどをWorkload Modelへ反映します。

そのうえで負荷を段階的に増加させ、Response Time、Throughput、Error Rateと、Resource、Saturation、Queueの関係を確認します。

性能試験の目的は「最大何TPS出たか」だけを求めることではありません。どのWorkloadまで、どのResponse Timeで、どの程度の余力を残して安定して処理できるのかを明らかにすることが重要です。

さらに、ピーク、過負荷、縮退、障害、長時間運転、復旧まで確認することで、実運用に近い性能特性を把握できます。

参考文献

  • Brendan Gregg 著、長尾高弘 訳『詳解 システム・パフォーマンス 第2版』オライリー・ジャパン。特に12章「ベンチマーキング」の、ベンチマーキングの失敗、シミュレーション、Active Benchmarking、USE Method、Workload Characterization、Ramping Load、Sanity Check、Statistical Analysisの考え方を参考にしています。
  • Brendan Gregg, Systems Performance: Enterprise and the Cloud, 2nd Edition, Chapter 12 “Benchmarking”, Addison-Wesley Professional.

コメント