前回と似た話で、計測時の性能単位についてサクッと考えていきます。
どのような単位を意識し、どのように性能値を算出していくと、より信頼できる安定した結果になるのか、です。
単数と複数
システムの世界において、特にアプリケーション作成ではデータが単数か複数かで扱いに大きな違いがでます。インフラ・リソースにおいても同様で、単数と複数では性能値の特徴に、僅か~大きな差が出たり出なかったりします。単体で稼働するシステムは、その処理内容がシンプル── というよりは、複数になると途端に処理や仕組みが複雑になります。これは並列処理やクラスタ構成のようなシステムを、少しでも作成に関わったことがあれば当然のように体感することです。複雑ということは、オーバーヘッドが発生したり管理が難しくなるわけですが、その代わりに拡張性や冗長性をいくらか得られることになります。
負荷試験においては、最初から想定する大規模リソースで行ってしまうと、このリソース量の変化に関わる特徴を見落とすことになるので旨くありません。
手順の基本としては、まず単数での計測を行い、次に複数、より多い複数とステップアップします。もし次の上位単位があれば、またその単数から複数へと計測と考察を続けていきます。
大規模から小規模へ変化させると、その特徴を捉えるのが難しいですし、なによりそんな手順を踏もうとする輩はいないでしょう。小から大へと細かく計測し、数字を採取するだけではなく、その特徴を捉えようとする姿勢が試験において重要になります。
単位
負荷試験におけるX軸の単位は色々できますが、ここではリソース量について注視します。1vCPU
負荷をかけて処理をフル活動させようとしたとき、その最小単位となるのが 1vCPU です。適切なインスタンスとしての最小が 2vCPUs からなら、アプリケーション・サーバーの 1worker (or 1process or 1thread) という設定調整での単位とします。一口に1vCPU = 100% としての性能を計測するといっても、条件で計測値が変化します。負荷Clientが連続的にリクエストしたとして、例としてはこんな感じ。
Client数 | Worker数 | CPU状態 | レスポンスタイム |
1 | 1 | 微妙に100%に足りない | 正常 |
2 | 1 | ほぼ100%になる | Worker不足によるレイテンシ発生 |
2 | 2 | 確実に100%になる | vCPU不足によるレイテンシ発生 |
1つのリクエスト処理が完了するまでは大雑把に書くと
User → Request → Web → App ↔ DB/KVS
User ← Response ← Web ←
と一連の流れがあり、当たり前ですけど、AppサーバーのCPUが稼働するのはAppの部分の処理だけになります。なので、1 : 1 で負荷をかけても、ネットワーク等のレイテンシによりAppをフル稼働させることが微妙にできなかったりします。
となると、1vCPU = 100% としての計測値を確実に採取したいならば、vCPU数より多いClient数が必要になります。そして、Client数に対してWorker数が足りないと、接続待機またはエラーが発生するので、Worker数もまたvCPU数より多い方が確実になります。
概ね1vCPU=100%での計測値を採取できれば良い、という考えでもある程度はイケるかもですが、ただ漠然と行う負荷試験ではいつかどこかで痛い目を見るでしょう。
正しく最小単位での計測と理解をし、複数vCPUsでの計測をした上で、その変化の特徴を観察して考察していきましょう。
1Server
1Serverでの最大性能を計測すれば、複数台に増台させていったときの変化を観測できるというのは、vCPUの時と同様です。1つのServerをフル活動させるということは、16vCPUs なら 1600% のCPU使用率になるよう、負荷をかけるということです。
これは先程のvCPUでの考え方と同じで、ClientやWorker数はvCPUsより大きいほうが安定してCPUフル活動させられるので、vCPUs の 1.5 ~ 2.0倍 を目安として設定し、負荷をかけることになります。
仮にvCPU単位での考察が面倒だとしても、ここだけはきっちり計測しなくてはいけません。複数台のサーバーが、並列関係なのかクラスタなのか、などで重要度は変わりますが、ここの増台変化が最もスケールアウトに関与するためです。
1Cluster
クラスタという構成は、通常はサービスにおいて1つのクラスタでスケールアウトを完結して運用したいものではありますが、拡張性や制約、はたまたデータ都合での垂直分割など、場合によっては複数クラスタを必要とすることもあります。ここまでくると、均一な台数・構成になることの方が難しいかもしれませんが、それゆえにクラスタとしての最小構成での性能値をしっかり把握しておく方が、より最適に近い設計ができるというものです。
1Clusterのキャパを倍にするのか、2Clusterとして増やすのか、では運用事情がだいぶ異なります。また、クラスタにはたいてい、管理用リソースや予備リソースが付き物なので、その特徴も含めてとなると、よりいっそう最小構成での正しい理解が後の強みになること間違いなしです。
複数量の計測
これらの最小単位を元に、量を増やしていった際に計測値がどうなるか、を観測していきます。ほぼ比例していけばそれが最も良い結果ですが、もし劣化するタイプのシステムの場合、一定量以上を超えたどこかでレスポンスタイムやコスト・パフォーマンスが許容できない境目にぶつかることになります。
それによって、システム自体を再考するのか、チューニングするのか、またはそこを上限と認識して拡張する方向性にするのか。色々考える必要がでてきます。
サービスに必要な処理量が想定されていれば、そこまでリソース量を増やしていった時に、想定外の異常なく動作保証できれば十分ではあります。が、サービス想定とはまた別に、システム運用者としてはその先を必要とされた場合にどうなるのか、どう対処していくことになるかを考察できる状態になっているべきです。
そのためにも、一歩ばりに小さく細かく速い試験、最小単位からの丁寧な計測がモノを言うはずです。
本番試算
負荷が小さい方から大きくなると、システム挙動がどうなるかは予測しきれない部分がありますが、大きい状態から小さくなった時は想定以上にパフォーマンスが下がることはほぼありません。最小単位100%で計測した値は、例えば50%の出力では通常、想定通りの50%もしくはそれより少し良い性能を発揮するでしょう。
裏方のジョブ系システムだと100%フル活動させても問題なかったりするので、Globalに公開するシステムのことを考えるとすると、利用状況が100%に近いとユーザーがアクセスできなくなるので、最大で50%前後の利用率になるようスケールアウトやスケールアップするのが普通です。
ということは、試験で得た結果を元に、想定最大トラフィックを捌くためのリソース量を算出し、それに (100 / 50%) をかければ、きっかり利用率が 50% になるリソース量になるというわけです。
これらは皮算用でもなんでもなく、実際に私が負荷試験で実践していることの1つです。
ただ、場合によっては100%までブン回せない場合もあるので、80%程度でヨシ!としてその先の算出をすることもあります。肝心なのは、最終算出結果が、危うい可能性を含むのではなく、より安全な方向性のモノであるということです。
安全気味に振って算出した上で、結果的に本番投入後にリソース過剰だとしてもそれもヨシ!で、クラウドなので数日後にリソース量を最適化すればいいだけです。
オンプレだとそうはいかないわけで、クラウドのおかげで負荷試験の精度も多少は緩くできるところは、非常に助かるポイントだったりします。
正しい負荷試験は概ね本番運用に反映されますが、それでも試験は所詮試験なので、本番投入から初ピークタイムを越すまではドキがムネムネするものです。
正常に越せた時は「想定通り、問題ないです」って態度をとるけど、実際は100%の保証はないからな~って心持ちで無事を祈ってたりします:-)