負荷試験#全体フロー概要

負荷試験シリーズ、書きたいことはイッパイある気がするんだけど、技術の総括的な感じがエグくて、どうしてもまとまりがなくなってしまう……

ということで、気分転換にザックリお絵描きしました。これで少しはテーマを切り取って小綺麗に書いていきやすくなったはず。



負荷試験の流れ

それがこれじゃ!いくらでも肉付け項目が出てくるだろうけど、1画面に収める内容としては最小限としてほどよくまとまったはずである。



だいたい分かってもらえると思うけど、一応軽く説明はしておきます。長くならないよう、一言二言ずつで!


環境



クライアント・リソース

負荷試験ツールを動かすためのサーバー(群)。EC2 や ECS Fargate などのスポットで起動して安く済ませる。使い捨て用途なので、環境一式を作ったり削除したりを、一手で簡単にできるようにしておくと吉。

負荷試験ツール

疑似ユーザートラフィックを発生させるためのツール。負荷試験#ツール選択 に書いたので参照。

ユーザーリスト

user_id のようなDBの PrimaryKey や、UUID のようなユーザーで一意なデータのリスト。アプリケーションで(疑似)認証するためのものなので、その都合に合わせた項目で、都合のいいように扱えばいい。

シナリオ

リクエストをどのような内容と割合で送るのかを表現したもの。ツール準拠の形式であったり、コードで記述する場合など様々ある。作成と調整に時間がかかる所なので、いかに楽にやるかが重要なポイントとなる。

サーバー・リソース

アプリケーションを動かすためのサーバー(群)。どのようなリソース量で試験計画すれば、試験の早さと精度を上げれるかの考えどころとなる(参考:負荷試験#性能基準単位)。

ソフトウェア・ミドルウェア

稼働に必要な各種パッケージのインストールや設定など。とはいえ、ここでいちいち手作業するわけではなく、本番用イメージを流用するなり、別途コード化がなされているべき。クラウドの一部マネージドサービスくらいは、この時だけポチポチしても可。

アプリケーション・コード

アプリケーションのコード一式を配置し、環境変数といった設定をしておく。ログなどを余計に出したり、逆に外部に不要なリクエストを送らないようになど、負荷試験環境として適切な内容にする。

テストデータ

主にデータベースの試験用データ。新規サービスならばお手製の想定データになるが、既存サービスなら本番バックアップをリストアして、よりリアルなテストにもできる。データの量や偏りがどのくらい必要かは、試験の目的によって変わるので考えどころ。


試験



試験実行

負荷試験ツールを実行し、トラフィックを発生させる。採取の目的によって数十秒から数十分まで必要な長さが変わるが、何度も実行するため、1回1回を必要以上に実行せず、極力最低限の時間で必要な結果を採取できるよう、各所を調整して時間を節約すべし。

試験結果確認

負荷試験ツールが終了後にアウトプットしてくれる結果を確認する。まずは自身の想定通りのスループットやユーザー数で流れているか、修正対象なエラーが出ていないか。それらが正常な上で、性能品質として許容範囲かどうかをチェックしていく。

その他の結果確認

ツールの結果以外に、クライアント・サーバー双方のリソース使用状況をメトリクスで確認する。サーバーの各種項目でキャパシティを判断するのは当然として、見落としがちなクライアントで詰まっていないかも見る(参考:ミドルウェア性能検証の手引き)。ログはケチらず出せるものは出して、現象確認をしやすくして時間を節約する。

試験内容調整

目的とするトラフィックが得られない場合、ユーザー数やスループットを調整してやり直す。リクエストごとのスループットやエラー率が気に食わない場合、シナリオを調整してやり直す。その時はダメだった結果も逐一記録していき、後でやり直す必要のないようにしておく。

リファクタリング

遅いスループットのリクエストの処理を改善したり、エラー率の高い部分を修正してやり直す。負荷試験を実行するということは、単にトラフィックを流し込んで記録するだけではなく、リファクタリングする箇所を判断したり、実際に修正案を出したり、修正することも含む。と考える。


結果



単位あたりの性能

まずは、あるスペック1台あたりでの性能を採取し、それに比例することを基本として考える。複数が大事な場合は2台で十分。いきなり大量台数で試験してもあまりいいことはない。徐々に台数を増やし、比例しない現象がボトルネックやキャパシティ推測要因であるとみなして進めるべし(参考:負荷試験#性能基準単位)。

障害対策

負荷試験は”大丈夫”であることを確認するが、逆に言うと”大丈夫じゃない”条件も把握できるということ。それがアプリケーション起因ならばコーディングやスキーマ変更で修正するが、インフラリソース起因ならばアーキテクチャ改善で対応することになる。

懸念材料

”大丈夫じゃない”現象にも色々あって、OSやミドルウェア、クラウドとしての設定上限値に引っかかることがあり、負荷試験で炙り出せるかは”知ってる”か”知らない”かの差が大きい。普通はスルーしそうな、扱うシステムのドキュメントを読み込むのも仕事である。あとは数ヶ月・数年後の経過データや、ヘビーユーザーよるデータの偏りなど、どこまで想定するかの勝負もある。

本番想定条件

新規サービスならば見込みでユーザー数・トラフィックを想定し、その流量を保証しつつも、その先の対応もある程度見据える必要がある。既存サービスならば、リアルデータもあるし現行条件での動作を保証すればよいので、ある意味安定する。『嬉しい悲鳴』は逃げの言葉であり、想定と対策が甘いだけだが、どうしようもないこともある。にんげんだもの。

本番リソース算出

小さい単位で精査された結果と、本番想定の流量をかけ合わせると、本番に必要なリソース量を算出できる(参考:負荷試験#計測値の比例と事例)。最終的には実際にそのリソース量でも試験するし、その保証された構成から、ローリスクで費用節約する方法も考えていく。インフラ費用は利益に直結するので、お金のことを考えるまでが負荷試験である。


感想戦

世の中、色んなアプリケーションがあって性質は様々だし、試験者にも得手不得手があるので、こういう風に進めて、こういう結果を導き出さなければならない!とは言えない。

しかし、ただツールを使って、トラフィックを流し込んだぜ!みたいな負荷試験もあって、それ何を目的にして、どういう意味の結果が出たのか、が全然見えないこともしばしばある。

100%落ちないシステムが存在しないのと同じく、パーフェクトな負荷試験もないんだけど、それでも全体の流れに意味と効率を求めるための、基本を抑えていくことが大切だと思った次第です。

その上で、あとはやるだけ。外科医の執刀みたいに、捌きまくってなんぼの業務だと思います(結局、経験かい!みたいなオチでスマソ:-)