負荷試験#開始と目的 の続きで、最初から目標を大きくしすぎず、アプリケーションと目的をなんとなく理解して、とりあえず始めていきましょうというところです。
どのようなデータを採取し整理すれば、ゴールに向かっていきやすいのか、を考えていきます。
目次
条件と結果の記録
負荷試験には多くの関連項目があります。項目1つの記録や考察が抜けていただけで、最初からやり直し、ということも普通にあります。最初から完璧な試験はなく、進行したことで判明する要素もあるので、最初から最後まで項目を決めつけて記録することは非常に危うく、常に今現在の試験が正しいのか、設定は最適なのかを疑う姿勢が必要です。
また、途中で項目数が変動する可能性があるということは、それまでの記録が一瞬にしてゴミに変わる可能性が常にある、ということなのですが、例えゴミだとしてもそれがゴミである証拠は必要ですし、それがなければゴミである確認のための再試験をする場合もあり、時間のムダが生じやすいところです。
そのため、まず絶対的に守りたいこととして、その試験中において認識している固定値・変動値は、可能な限り記録しながら進行しましょう、ということです。
多少、項目が多く面倒だとしても、項目を欠いてよくわからなくなるよりは、結果的に時間の浪費を抑え、精度を高く進行できることは確実です。なんとなく始めつつも、早い段階で記録を整理し始めることが、基本であり奥義にもなります。
記録する項目
それでは、どのような記録すべき項目があるのかを整理していきます。認識する値といっても、たいして関係のないカーネルパラメータは?とか、野暮なツッコミは不要です。また、ツールやアプリケーションによって、いくらでも異なるので、あくまで参考例ということで。Target
まずは大事な目的から共有します。ここでは3つほど例を出します。仮で立てた目標値も、本番のそれとは色々剥離する部分も起きますが、それでも予測値として計画し、それをクリアすることを目的として進行することになります。
ユーザー数ベース
例えば、DAU = Daily Active Users はこれくらい、と想定して計画し、それを捌けるサーバーリソース量になるよう試験します。実際に知りたいリソース量は1日の中でのピークタイムなので、12時 や 21時 において、その DAU ならどれくらいの RPS = Requests per seconds になるのかを試算し、それを負荷試験ツールで発生させる最終的なトラフィックとして試験を進行します。
リソース量ベース
サーバー性能は単体・クラスタ構成に限らず、スケールアップ・スケールアウトには必ず上限が存在します。特にオンプレミスは発注から利用開始までの時間が必要ですし、クラウドは即変更可能なだけでスペックに上限があることに変わりはありません。想定しているサーバー構成と環境において、現実的に最大限用意できるサーバーリソース量ならば、どれくらいの DAU やトラフィックを捌くことが可能か、という方向での試験も時には有用です。
とはいえ、基本的には DAU ベースで試験しつつ、もしそれが想定外に増大した時にどこまでイケるのか、というその先を知っておくための補足的な試験となることでしょう。
同時接続数ベース
DAU やトラフィックとは少し毛並みが異なる性質で、HTTP(S) のような1リクエストがせいぜい 100ms~3s 程度で独立しているモノではなく(一応 KeepAlive はあるけど)、ある瞬間に何ユーザーがサーバーに対して同時に接続を保ち続けるのか、というプロトコルもあります。同時接続数の場合、トラフィック負荷だけではなく、接続数の上限やメモリ容量が重要になることが多く、システムによっては明確に1サーバーあたり1000接続まで、など区切りをつけてリソース量の増減を考える必要があります。
Client Specs
意外に記録を見落としがちな、ツールを使ってトラフィックを発生させる Client の環境条件です。項目 | 補足 |
サーバースペック | インスタンスタイプ、vCPU数、CPUモデル、など |
サーバー台数 | EC2、コンテナタスク数など |
Worker数 | 1台あたりのWorker数と全体の数。ツールがクラスタ可能か、シングル or マルチスレッドタイプかで必要性は変わる |
Server Specs
Server側はまさに被試験体なので、基本項目もそれ以外も多く確認することがあります。リファクタリングやチューニングを試みると、注意する項目が増えていきます。項目 | 補足 |
サーバースペック | インスタンスタイプ、vCPU数、CPUモデル、など |
メモリ容量、ストレージ性能(IOPS,Latency)、ネットワーク性能 | |
サーバー台数 | EC2、コンテナタスク数など |
接続数・スレッド数 | 各種ミドルウェアの、最大受け入れ同時接続数や、並列稼働Worker数など |
設定 | 調整に関わるOSやミドルウェアの各種設定値 |
Data
データベースなどのテストデータの変化による結果の変化をチェックしていく場合、その特徴を記録しておきます。大雑把に書きますが、実際にはモノによって詳細に記録することになります。- データ容量
- データ件数
- データ分布・割合
- データ分割条件(垂直・水平・分割数など)
- データ保存形式(暗号化・圧縮など)
- データ転送形式(暗号化・圧縮など)
Client Conditions
負荷試験ツール実行時の、トラフィック流量決定条件です。ツールによって異なるので、可能な変動値を全て記録します。項目 | 補足 |
Users | 最大同時実行ユーザーセッション数 |
Spawn | 1秒毎に何ユーザーセッションずつ増やすか |
RunTime | 試験実行時間 |
WaitTime | リクエスト間毎の待機時間 |
Metadata | レスポンスに影響を与える HTTP Header など |
Test Result
Stress Tool
負荷試験ツールが出力するテキストやグラフの結果をまとめます。徐々にトラフィックを増やす場合、ピーク部分のみ記録したり、異常な形状のグラフ部分を記録します。項目 | 補足 |
RPS | Requests per second 毎秒あたりのリクエスト数。RPM (per minite) より秒がオススメ。全体としてのと、必要なら処理ごとも残す |
Failures/s | 毎秒あたりのエラー数やエラー率。全体と、特にゼロではない処理 |
ResponseTime | レスポンス速度を単位はms(millisecond)がオススメ。min/max/avg を、全体の平均と特に遅い処理を |
ResponseSize | レスポンスのデータ平均容量。全体の平均と特に大きい処理を |
Users | 予定通りのユーザー数増加と最大数に到達したかチェックし、ダメならファイル・ディスクリプタ数や、プロセスID数など、接続上限数に関わる設定を確認します |
Logs | ツールの実行ログに異常があれば残す |
Application Action
アプリケーションの処理ごとに、特に遅い数値が出たりエラーが発生する箇所をまとめます。エラーはそもそも異常なので、シナリオ・負荷条件やアプリケーションの修正が必要です。
遅い箇所は原因の特定やリファクタリングが必要な箇所なので、遅い順に優先度を上げて、調査依頼または自身で改善案を提示します。
SaaS
NewRelic や Datadog といった監視サービスを適用している場合、負荷試験ツール視点だけでは見えない部分も調査できるので、同時に共有していきます。特に処理単位を Transaction と表現しているはずなので、その合計処理時間(Total Time)や遅い処理(Slowest)順に上からピックアップします。
その中で、特に着目したい詳細処理が見つかった場合、その共有用URL を結果に貼り付けて共有するとよいでしょう(スクショは基本せず、SaaS を見れない人用くらい)。
Client Metrics
ツールを実行しているサーバーのメトリクスは、特に最初の方は必ず確認します。サーバーがキャパオーバーで詰まるのは試験上問題ないですが、クライアントが詰まると正確な試験にならないからです。項目 | 補足 |
CPU | CPUの使用率が100%に到達しないよう調整します |
Network | NetworkのBandwidthが上限に到達しないよう調整します |
Memory | ユーザーセッションを増やしすぎるとメモリ不足になるので注意します |
Server Metrics
サーバーメトリクスの基本項目とミドルウェアごと専用の項目を記録し、適切な処理量と性能上限の算出に利用します。項目 | 補足 |
基本項目 | 参考:ミドルウェア性能検証の手引き | 外道父の匠 |
クラウド | マネージドサービスとして提供される各種メトリクス |
サーバーステータス | ミドルウェアに直接リクエストすることで得られる各種ステータス値 |
記録媒体
試験の始めたては、試験そのものがちゃんと動くかを確認し、それから手探り気味に目的に向かって本格的な調整をしながら実施します。そのため、最初は何も記録しなかったり、適当なテキストデータにメモ書きして進めることがありますが、これは早い段階で社内情報共有ツールや表計算ソフトに記録することをオススメします。
採取値を使った計算は、そう複雑なものは多くないですが、試験数が増えるほど表計算になっていたほうが当然楽です。また、自分で見るにせよ他人と共有するにせよ、テキストや箇条書きも多くなるほど見づらくなるので、表に落とし込む方が結果の記録も整理も効率的です。
美しくない自身の記録行為が億劫になってモチベが下がっても仕方ないので、初手の試験後には、そろそろちゃんと整理し始めた方がいいかな!って気付けると良いです。
試験の実行時間
多くの試験は、数回程度で済むことは少なく、数十回は実施することになります。そのため、試験の実行時間だけでも合計すると結構なモノになるため、1回1回の試験時間を最適化することは大切です。悪い例としては、サービスのとあるイベント実施が30分間あるとします。アプリケーションの設定も30分単位でしか設定できないし、試験も実際の時間と同じだけ実行した方がいいでしょう。という考えは誤りです。最終的な確認試験としてはアリですが、初手~中盤までを30分ずつ実行する必要はありません。
理由は、判断材料としての結果採取には普通は30分も必要ないからです。大雑把に言えば、必要なデータが採取できた時点で、その試験はいったん打ち切ってよく、打ちきれず最後まで実行する必要がある場合は、先に最小限の実行時間を判断してから、繰り返しの実施に入るべきです。
では、何を採取できればOKと判断するかというと、メトリクスの採取が基本となります。メトリクスの多くは、1分または5分間隔でデータが更新されるので、メトリクス値の変動が安定期に入ってから2~3回分あれば、その後のデータは不要です。5分間隔ならば、15分実行すれば2回分は確実に採取され、点ではなく線のデータとなります。最近はほとんどが1分間隔だと思うので、より短時間で十分であることが多いです。
試験実行時に、長いからとインターネット徘徊しても別にいいんですが、理想的には試験実行終了後にはすぐ次の条件で試験を回し、それが回っている間に前の試験条件と結果を整理する。というように交互に回転することが最も効率的です。
ハードウェア単体の試験だと、OS上で秒単位で観測するので、もっと周期が早かったりします。逆にどうしても長くせざるを得ないのもあるでしょうし、大事なのは所要時間の最適化をしようとする姿勢ということで。
データ整理
実行条件と試験結果を表に整理していくと、数値が綺麗に比例するもの、しない箇所が出てきます。比例しない場合で、かつ特にそれが許容できない変化の場合は、原因を探って、必要があればその項目を試験に組み込んで再実施します。この時点ですでにデータから何かを判断しているわけではありますが、これを納得のいくデータになるまで繰り返し、次のフェーズであるデータの判断と算出へと移っていきます。
できれば、データ採取をガーッと全部を終わらせてから考察に移れたほうが効率的だし幸せなのですが、なかなかそういかないこともあります。それを上手くやるには、データ採取の時点で異常や不足に気づいて試験を調整していく洞察力、これで十分だという判断力が必要です。
ですが、それを磨くには多くの結果考察の経験が必要で、そう考えるといきなり上手くやってみようとするよりは、まずはやってみるべし!で、途中や終了後に、試験自体を振り返って改善しようとする姿勢が、もっとも重要なんかなとも思ったり:-)