負荷テスト on AWS のすすめ

第 2 回 : 負荷テストを計画しよう

2023-09-01
AWS ソリューション紹介

馬渕 俊介

みなさん、こんにちは。ソリューションアーキテクトの馬渕です。AWS 入社前は SIer で性能試験・性能問題解決に特化した部署におり、さまざまな業種のお客様のシステムに対する支援を実施していました。

本記事は、世界中のユーザーが直面する一般的な問題の解決策を提供する AWS ソリューションライブラリ の人気ソリューションの一つ、 分散負荷テスト ソリューションを活用いただくための記事となっています。負荷テストを有効に実施するためには、ツールそのもの以上に負荷テスト全体のプロセスに関する理解が重要となるため、全 3 回の記事シリーズの第 1 回となる 前回の記事 ではまず負荷テストの全体像をご紹介しました。

Part 1:負荷テストの全体像を理解しよう (前回)
Part 2:AWS での負荷テストを計画しよう (今回)
Part 3:AWS での負荷テストを準備・実施しよう

今回の記事では、負荷テストの計画で必要となる各種タスクについて解説するとともに、 AWS サービスで関連する点について解説していきます。

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

前回の記事でご説明した通り、性能試験は計画・準備・実施 (複数回)・評価の 4 フェーズに分かれます。計画で決める 1 個 1 個のものごとが性能試験の全体的な品質を決めるため、注意深く検討していく必要があります。本記事では、性能試験計画で実施するタスクをそれぞれ解説していきます。


本題に入る前に : 性能試験の種類と言葉の定義

本題に入るまえに、「性能試験」「負荷テスト」などの言葉の定義について確認しておきます。

性能に関連する試験の名称については、「負荷テスト」「ロードテスト」「ラッシュテスト」「ストレステスト」「限界テスト」など、各社様々な呼び名で、様々なスコープのテストを定義しているようです (※1)。本記事における用語の定義も兼ねて、ここで性能試験の種類について一度整理しておきます。

※1 IPA 刊行の「高信頼化ソフトウェアのための開発手法ガイドブック」では、国内のシステム開発会社各社のプロセス上で定められているテストが横断的に記載されていますが、性能関連のテストの名称が 20 件近く存在していました。同じ単語であっても別のスコープを指しているケースもありえるため、性能試験の実施にあたっては言葉の目線合わせをしておくことをおすすめします。

まず、オンライン処理について考えていきます。オンライン処理の性能を図る指標としてはレスポンスタイムスループットがありますが、単体のリクエストでレスポンスタイムが遅く目標のレスポンスタイムを満たせない場合、大量クライアントからのリクエストでも目標レスポンスタイムを満たせません。したがって、まずは単体でレスポンスタイムを測定して問題がないことを確認する必要があります (①オンライン単性能試験)。

次に、オンラインの各処理で単体レスポンスが問題ないことを確認できたら、大量のユーザからのリクエストを模擬しての試験を行います。負荷クライアントからオンライン処理を大量にかける = 負荷がけを行い、性能目標として定義した負荷比率・負荷量で、エラーなく・目標のレスポンスタイム内でシステムが処理しきれることを確認します (②ピーク性能試験)。

加えて、その負荷の比率のままで負荷量を 120%、140%、etc・・・といった形で増大させ、システムが応答できなくなる負荷量を確認します (③限界性能試験)。その際には、どこがシステム性能のボトルネックになるかどうかを確認し、Next Action の検討に繋げます。

また、アプリケーションのバグにより、処理をし続ければ続けるほどメモリリークが発生して性能が劣化したり障害に繋がったりするケースがあります。長時間連続してシステムに負荷をかけることでそういったケースを検知するという試験も性能テストの一環として行います (④長時間負荷試験)。

また、バッチ処理についても性能試験が必要です。バッチ処理も、実環境ではオンライン処理や他のバッチ処理と並走しうるものですが、単体で実行して目標の処理時間に収まらなければ実環境でも目標時間に収まりません。なので、まずバッチ処理単体での性能試験を実施します (⑤バッチ単性能試験)。

複数のバッチ処理がジョブネットとして実行される場合、バッチ処理が複数並走して実行される形となるため、単体より遅延するケースが想定されます。そのため、実際のジョブネット全体を実行して処理時間を計測し、運用上問題のない時間に収まることを確認する必要があります (⑥バッチ複合試験)。

そして、実環境においてはオンライン処理とバッチ処理が並走するため、その環境下でオンライン処理・バッチ処理がともに性能に問題がないことを確認する必要があります (⑦オンライン・バッチ並走負荷試験)。

本記事シリーズでは、「性能試験」「負荷テスト」という単語を以下のように定義します。

  • 性能試験 : システム性能を担保するために実施するテスト全体を指すものとして定義します。上に挙げた試験種別をすべて包含する、テストの大きな 1 カテゴリを指します。
  • 負荷テスト : 「負荷クライアントを用いて、オンライン処理の負荷を発生させるテスト」として定義します。すなわち、上に挙げた試験種別のうち「②ピーク性能試験」「③限界性能試験」「④長時間負荷試験」「⑦オンライン・バッチ並走負荷試験」がその対象となります。

1. 負荷テストの目的・目標・項目の決定

負荷テストの目的定義

前回の記事で、負荷テストでは以下を確認するとお伝えしました。

  • アプリケーションが、予想される最大量のアクセス量 (スループット) をエラーなく処理することができるか、その際にもレスポンスは目標のレスポンスタイムに収まっているかどうか (ピーク性能の確認)
  • アプリケーションが、目標のレスポンスタイムを遵守しながらどれだけのアクセス量を捌くことができるか、性能の限界に到達するときのボトルネックはどこにあるか (限界性能の確認)

そのためには、アプリケーションの性能目標を定量的に決定する必要がありますが、これは言い換えると「そのシステムで最大の負荷が発生するシチュエーションを想定し、その負荷を予測する」ということになります。

ビジネス観点とシステム観点の両面からシステムの性能を守るべきシチュエーションを抽出し、負荷テストの目的として定義していきます。

目的定義例) 20XX 年 XX 月に実施する大規模セールにおいて、以下の負荷に耐えられることを確認する

  • セール開始のプッシュ通知直後のアクセス集中 (ビジネス観点)
  • セール終了間際の駆け込み購入 (ビジネス観点)
  • セール初日の〆処理バッチと、翌朝のプッシュ通知が重なる時間帯 (システム観点)

負荷テストの目標性能定義・試験項目定義

想定するシチュエーションを定めたら、次にその内容を定量的な数値に落とし込んでいきます。試験対象システムが既存システムのリニューアルであれば、過去の類似シチュエーションでのアクセスログ・メトリクスから実績を算出したうえで、利用ユーザーの伸び率を考慮して目標として定義することが多いです。新規システムの場合は、ビジネス的な想定・要求事項からある程度決め打ちして目標を定義していきます。

目標性能定義例)

  • 閲覧ピークでの負荷比率で XX rps のオンライン負荷
  • 購入ピークの負荷比率で XX rps のオンライン負荷

目標値が決まったら、負荷テストの目的として想定するシチュエーションや、冒頭で紹介したい性能試験の種類分けに照らし合わせ、負荷テストとして実施すべき項目としての洗い出しを行っていきます。

負荷テスト項目定義例)

  • ピーク性能試験 ① 閲覧ピーク負荷モデル XX rps
  • ピーク性能試験 ② 購入ピーク負荷モデル XX rps
  • 限界性能試験 : 閲覧ピーク負荷モデル、ピーク比 何 % の負荷量まで処理可能か測定
  • バッチ並走試験 閲覧ピーク負荷モデル XX rps + ◯◯バッチ並走
  • 長時間負荷試験 : 閲覧ピーク負荷モデル、ピーク比 XX % の負荷量で、 ◯◯ 時間の負荷を実行

2. 負荷シナリオ・比率の決定

負荷テストの実施にあたっては、システムに発生しうるすべての種類のリクエストを模擬するのはおよそ現実的ではありません。システムに発生しうるリクエストを多い順に並べて、累積で 80 % や 90 % などの基準を設けて負荷テストでの再現対象として選定します。

また、ビジネス上重要なリクエストで比率から漏れるものがあれば、それも別途再現対象として選定します。負荷テストでの対象とするリクエストの比率を負荷モデルと呼びます。アクセスログの分析やユーザー行動の想定からこのモデルを決定していきます。

負荷モデルを決めたら、次にシナリオ検討です。ユーザーがトップページにアクセスして、商品を検索してカートに投入して、購入する・・・といったユーザーの行動の流れをシナリオとして設計し、負荷モデルに合うようにそのユーザー比率を定めていきます。

シナリオの検討においては、システムの実際の使われ方に対する理解・洞察が必要です。例えば、EC サイトにおける購入処理などの更新系の処理を模擬するためには、その前のユーザーの行動 (ログインやカート投入など) が必要になります。購買処理の負荷を精度高く模擬するためには「1 注文あたりのカートの商品件数」なども考慮する必要があるため、それに従ってシナリオの遷移順序 (上図のシナリオ③のように、商品件数を考慮してカート投入フローを複数回実行するなど) も設計していきます。

個別のシナリオを決定したのち、それぞれに対するユーザーの割り振りを決めることで最終的な各リクエストの比率を調整し、負荷モデルに近づけていきます。負荷モデルと 100 % 同一の負荷比率を作り出すことはできないため、精度と工数のバランスを考慮してシナリオ数やユーザー比率を定めていきます。


3. 前提条件の決定

負荷テストを実施する際に考慮すべき条件は、システムに発生させる負荷量だけではありません。システム性能に影響する条件として、例えば以下のような点を負荷テスト時に考慮する必要があります。

DB のデータ量・カーディナリティ・ヒットデータ率

DB 上に保持されているデータの状態はシステム全体の性能を大きく左右します。そのため、負荷テストの実施にあたっては、負荷テストの目的として定義したシチュエーションにおける DB の状態を負荷テスト環境で模擬する必要があります。観点としては大きく 3 つあります。

① レコード数 : レコードが 1 件しかないテーブルと、レコードが 10 億件あるテーブルでは、当然ながらクエリした際の性能は異なります。過去のレコード数の変動傾向や、ビジネス要求とデータ保持期間などをもとに、想定シチュエーションで各テーブル上に存在するデータのレコード数を想定してデータを作成しておく必要があります。

② カーディナリティ : データのカーディナリティとは、テーブルのカラムに格納されている値のバリエーションの多さを指します。例えば、EC サイトの会員ランクに「一般」「優待」の 2 種類があるとすると、会員テーブルの会員ランクカラムの値のバリエーションも 2 種類となるため、このカラムのカーディナリティは低くなります。一方で、同じテーブルの 会員 ID カラムは会員の人数だけ値のバリエーションがあるため、カーディナリティは高くなります。
カーディナリティは、テーブルをクエリする際のインデックス検索の効率に大きく影響を与えるため、負荷テストにおいても重要なファクターとなります。データの作成時には本番同等のカーディナリティを再現する必要があります。

③ ヒットデータ率 : DB のレコードのうち、クエリで抽出対象になるもの・ならないものの比率も検討しておくことが必要です。実ワークロード中で DB へのクエリ時に 1 クエリあたりどの程度のデータが抽出されるのか、テーブル全体でめったに抽出対象にならないレコードがどの程度あるかなどを検討して、データに反映します。

これらを再現する形でデータをすべて手作りするのはとても労力のかかる作業です。そのため、もし既存システムのリニューアルなのであれば、既存システムの本番 DB のデータをコピーして匿名化・マスキングし、試験向けに必要な変更を加えるという方法が最もオススメです。既存の本番システムが AWS のマネージドサービスである Amazon Aurora や Amazon RDS 上で動いているようであれば、 DB のスナップショット作成→スナップショットからのインスタンス再作成や Aurora クローンにより、容易に DB の複製が可能です。

各種キャッシュ状況

システムには多種多様なレイヤーにキャッシュが存在しており、その状況によってシステム性能が影響を受けます。

  • OS レイヤー : バッファキャッシュ、ページキャッシュ、Slab キャッシュ、etc
  • MW レイヤー : バッファキャッシュ、パース済み SQL キャッシュ、リザルトキャッシュ、etc
  • キャッシュサーバー : Amazon ElastiCache など
  • CDN : Amazon CloudFront など

負荷テスト目的として想定するシチュエーションで、これらのキャッシュがどうなっているかどうかを検討します。例えば、「システム起動直後での高負荷が想定されるため、キャッシュが載っていない状態で処理する必要がある」などの条件がないかを確認します。


4. 試験環境の決定

負荷テストでかける負荷の内容や、その際のシステムの前提条件を検討したので、次に「それらを実現する環境をどう構築するか?」を考えます。これについて、「システム内部」「システム外部」に分けて説明していきます。なお、ここで言う「システム内部」とは、負荷テストの実施主体者が環境をコントロールしたり作成・複製できる範囲内を指します。

システム内部の環境について

システム内部の環境については、「負荷テスト環境専用に AWS アカウントを作成し、本番同等のスケールで環境を構築する」ということを強くオススメします。

オンプレミスでは、一度調達したリソースがその後使われなくなると無駄な投資となってしまうため、本番同等の環境を負荷テスト専用に調達するハードルが高くなっていました。そのため、他環境との相乗りや縮小版環境での負荷テストなどが行われることがありましたが、いずれもリスクがあるためオススメしません。従量課金というクラウドのメリットを活かし、IaC などを活用して本番同等の規模の負荷テスト専用環境を構築するようにしましょう。

  • アンチパターン① 縮小版環境での負荷テスト : 「本番の 1/N サイズの環境で目標の 1/N の負荷量を処理できた」ということは、「本番環境で目標の負荷量を処理できる」ということを保証しません。スケールアウト・スケールアップで解決できない性能問題 (例 : DB での Disk IO など) を見落とすリスクがあります。
  • アンチパターン② 他のテストのための環境と相乗りし、時間帯で環境用途を分けて負荷テスト : この場合、環境の用途の入れ替えのタイミングで DB 内のデータの入れ替えなどが必要となるため、オペミスにより試験用データを失うなどのリスクが考えられます (恥ずかしながら、私は前職で経験したことがあります)。また、DB 上の各種履歴やログなどを専有で残しておけないことにより、解析が難航するケースもあります。

また、負荷テスト専用環境を本番同等スケールで構築する際にも、 AWS アカウントを別環境と共有することはオススメしません。

  • アンチパターン③ AWS アカウントを他環境と共有 : AWS サービスのクオータには、 AWS アカウント単位で定められているものがあります。他環境と AWS アカウントを共有してしまうと、他環境とリソースのクオータの取り合いとなり、本番環境での実際の性能ボトルネックとは異なるボトルネックが発生して正当にテスト結果を評価できないリスクが発生します (※2)。

※2 例として、 AWS Lambda の同時実行数などが挙げられます。 AWS のサービスクォータの管理方法については、 AWS Well-Architected Framework の「信頼性の柱」に 様々なベストプラクティス が記載されているのでご参照ください。

システム外部の環境について

システムが稼働する際、少なからず外部システムとの接続が発生します。負荷テストにおいて外部システムとの通信が必要な場合、利用可能な環境に何があるかを確認する必要があります。

外部システム側の管理者が負荷テスト専用に本番同等の環境を立ち上げられるならば、それが最も理想的です。ただし、テスト実施中に外部システム側でボトルネック解析・トラブルシュートが必要になったときの対応体制については検討しておく必要があります。また、外部システム側のスループット・レスポンスタイムを常時確認できるように監視ツールを設定しておいてもらい、テスト中に都度確認していくことが必要となります。

また、利用可能な環境がない場合はスタブを構築して負荷テストを実施する必要があります。実環境と異なる性能が出ること、スタブの実装が必要となることから、性能試験の品質やコストに大きく影響します。スタブを作成する際にも、スタブがネックにならないようにスペック・MW を適切に選定するようにしましょう。


5. 負荷ツールの選定

負荷をかける対象が決まったら、今度は負荷を生成する負荷ツールの検討が必要です。本シリーズの題材である 分散負荷テスト ソリューションは、ここでの選択肢の一つとなっています。

負荷ツールには、 大きく分けて ① 自分の管理するローカルマシンや仮想マシンに導入するタイプ (ソフトウェア型) と、② シナリオをサービスにアップロードすると、サービスがそれに基づいてコンピュートリソースを立ち上げて負荷をかけるタイプ (サービス型) 、という 2 種類があります。

①のソフトウェア型の負荷ツールとして知られているものとしては Apache Bench、 JMeter、 Gatling、 Locust、k6 などが存在します。Apache Bench は単一 URL に対する簡易な負荷テストにのみ利用可能なツールであるため、本格的な負荷テストでは利用できません。JMeter は 1998 年からある歴史の長いソフトウェアであり、 GUI でシナリオ開発が可能ということもあり現在でも第一線で利用されています。他の 4 つはいずれも JMeter を利用するうえでの課題を解決するために生まれてきたツールですが、 JMeter と異なりコーディングが必要ということもあり、依然として多くの現場で JMeter が利用されている様子です。

②のサービス型の負荷ツールとしても複数のサービスが存在していますが、その多くは JMeter のシナリオに対応したものとなっています。 分散負荷テスト ソリューションもその一つであり、 JMeter で作成したシナリオをアップロードして負荷をかけることができます。

負荷ツールの選定のポイントとしては、以下のような観点が挙げられます。

  • 機能面
    • かけたい負荷をそのツールでかけることができるかどうか (プロトコルの制約やシナリオの制御など)
    • シナリオ実装担当者のスキルセットとマッチするか (GUI or コーディング)
    • レポーティング機能で望む出力が得られるかどうか
  • 非機能面
    • 負荷ツール側の性能
    • 負荷ツール側のスケーラビリティ
    • コスト

いずれの観点においても、分散負荷テスト ソリューションはメリットがあります。機能面の観点では、 JMeter のカバーする広範な機能を利用できるため幅広いシナリオ・プロトコルに対応可能であり、シナリオも GUI で作成が可能です。また、レポーティングについても、リアルタイムで同ソリューションのフロントエンドより確認が可能です。

非機能面では、コンテナの柔軟なスケールアウト性により負荷クライアントがボトルネックとなる可能性を減らすことができますし、終了後に即コンテナが終了することによる従量課金のメリットを享受できます。 同ソリューションは AWS CloudFormation テンプレートにより簡単に立ち上げることができるため、計画に際してぜひ一度立ち上げてみることをオススメいたします。


6. 監視ツールの選定・設計

 負荷テストを実際に行うフェーズでは、テストの 1 ショット (※3) ごとに準備→実行→分析→チューニングというサイクルを回す必要が出てきます。そのサイクルのなかで特に重要なのが分析で、いかにスピーディーかつ正確に問題箇所を特定するかが負荷テストのスピードと品質を左右します。そのためには、自動的に、網羅的に、高い解像度で、すぐに良し悪しが判断できるようにしておくこと、すなわちオブザーバビリティが実現されていることが欠かせません。ログ・メトリクス・トレースを適切に収集し、可視化できるようにしておきましょう。

負荷テスト環境でのオブザーバビリティの実現方針については、既に本番環境での利用ツールが定まっている場合はそちらを基本として考えるのがよいでしょう。負荷テストでの各種メトリクスの傾向を本番同等のツールで分析し、必要に応じてダッシュボード化することで、実際の本番環境での障害に備えた分析体制が整います。負荷テスト内で「O11y としてこの情報が不足している」ということを洗い出せれば、それを本番環境のオブザーバビリティ設計にフィードバックすることで本番環境の運用品質を向上することもできます。

O11y 実現方針が決まっていない場合、あるいは不足がある場合は、AWS のオブザーバビリティツールでどうカバーできるかを検討するとよいでしょう。 AWS ではネイティブサービス・ OSS マネージドサービスの 2 軸でツールを提供していますし、サードパーティのオブザーバビリティツールの多くで AWS に対応したメトリクス・ダッシュボードなどが用意されています。

AWS におけるオブザーバビリティについて学ぶにあたっては、 One Observability Workshop の活用をオススメします。AWS のオブザーバビリティサービスで何ができるかを詳らかに知ることができるワークショップとなっており、日本語訳もされているため理解しやすいです。

※3 本記事シリーズでは、負荷テストの一連の流れにおける 1 回 1 回の負荷掛けの実行を「ショット」と呼んでいきます。

負荷テストにおけるオブザーバビリティの Tips をいくつかご紹介しておきます。

高レベルのダッシュボードと低レベルのダッシュボードをうまく使う

Amazon Builders Library で紹介されている Amazon 自身のベストプラクティスとして、運用を可視化するためのダッシュボードの構築についての記事があります。こちらの記事にあるように、システム全体の挙動をサマリー的に理解するための高レベルダッシュボードと、その細部を網羅的に可視化するための低レベルのダッシュボードを用意しておくことを推奨します。

高レベルのダッシュボードではレスポンスタイム・スループットといった性能指標を即時閲覧できるようにしておくことでショットの結果評価を迅速化しましょう。低レベルのダッシュボードにおいては、単に OS の物理的なリソースだけでなく、 MW レイヤーの論理リソース (コネクションプールやスレッドプールなど) まで可視化しておくことが重要です。また、Amazon RDS や Amazon EC2 などのサービスについては Amazon CloudWatch の自動ダッシュボード が提供されているので、低レベルダッシュボードのひとつとして利用できます。

また、負荷テスト内で見えてきたボトルネックを踏まえて高レベルダッシュボードをアップデートし、そのダッシュボードを本番環境に転用することで性能問題発生時にすぐ問題を特定できるようにするのがよいでしょう。

システム内の各コンポーネント固有の監視方法を理解しておく

システム内には多くのレイヤーにわたってコンポーネントが存在します。AWS サービスについては、サービスごとに固有の監視機能があるため、どういった機能があるか、どう設定するのがよいかを検討しておくとよいでしょう。負荷テストにおける Tips をピックアップしてご紹介します。

  • Amazon RDS, Amazon Aurora : Performance Insights を有効化するとともに、 Amazon CloudWatch 拡張モニタリングを有効化しておきましょう。 CloudWatch の標準メトリクスよりも更に情報の詳細度が上がるため、ボトルネックの特定が容易になります。特に Performance Insights はデータ保持期間が 7 日間であれば無料で利用できるため、必ず有効化することをおすすめします。
  • Amazon EC2 : インスタンスの詳細モニタリングを有効化しましょう。デフォルトで有効化される基本モニタリングでは 5 分間隔でメトリクスが取得されますが、負荷テスト環境においては 5 分では時間の粒度が粗すぎて分析に苦労する可能性が高いです。また、 CloudWatch の標準メトリクスはハイパーバイザー視点でのメトリクスであるため、 OS 内の視点でしか取れないメトリクス (メモリなど) の取得が別途必要です。 CloudWatch Agent などを利用して取得するようにしましょう。

まとめと次回予告

今回の記事では、負荷テストの計画フェーズで実際に検討すべき物事についてご説明してきました。次回は、実際の負荷テストのなかで、分散負荷テスト ソリューションをどのように使っていくかについてご説明していきます。

それでは、また 次回の記事 でお会いしましょう !


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

馬渕 俊介
アマゾン ウェブ サービス ジャパン合同会社
エンタープライズ技術本部 ソリューションアーキテクト

交通業界のお客様を中心として、AWS の利用をご支援しています。
休日はバンドで演奏したり作曲をしたり、ボールやナイフをジャグリングしたりしています。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する