メインコンテンツに移動
AWS ソリューション紹介

負荷テスト on AWS のすすめ 第 3 回 : 負荷テストを準備・実施しよう

2023-11-01 | Author : 馬渕 俊介

はじめに

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

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

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

さて、今回の記事では、いよいよ実際の負荷テストの準備・実施について説明していきます。今回の記事シリーズの主役である Distributed Load Testing ソリューション (以下「 DLT ソリューション」と記載します) を使って、性能試験をコスト効率よく実現していきましょう !

お知らせ

このたび、 DLT ソリューションを用いた負荷テストを体験できるワークショップコンテンツ を公開しました。DLT ソリューションをデプロイし、負荷テスト対象のサンプルアプリをデプロイしたのち、同ソリューションを用いて実際に負荷テストを実施していく内容になっています。コストは 1 USD〜数 USD、時間としては 2 ~ 3 時間程度で完了できる内容となっています。
今回の記事シリーズで負荷テストに興味を持った方、負荷テストによいツールをお探しの方は、是非ともお試しください。こちら »


X ポスト » | Facebook シェア » | はてブ »

ご注意

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

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

builders.flash メールメンバー登録

builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。

今すぐ登録 »

今回の内容

第 1 回の記事でご説明した通り、性能試験は計画・準備・実施 (複数回)・評価の 4 フェーズに分かれます。前回の記事では性能試験の計画で検討・決定すべき内容を紹介していきました。今回は、準備・実施および結果評価について説明していきます。

A diagram in Japanese showing the complete workflow of distributed performance testing on AWS, including test planning, preparation, execution, and results evaluation. The image outlines step-by-step actions and roles in each phase, with emphasis on the test execution process as the article's main scope.

1. 負荷テストの準備でのタスク

さて、前回の記事で示したように負荷テストの計画が終わったら、実際にテストを実施するための準備に入っていきます。各タスクを説明するなかで、 DLT ソリューションを利用した場合の作業方法についても説明していきます。

負荷テスト対象となる試験用環境の構築

負荷テストの対象となるアプリケーションを、計画した通りにテスト用の環境に構築していきます。前回の記事で説明した通り、「負荷テスト環境専用に AWS アカウントを作成し、本番同等のスケールで環境を構築する」というのがベストプラクティスです。IaC などを活用して負荷テスト用の環境を立ち上げ、必要に応じて外部接続先のスタブなども構築していきます。疎通確認を行い、環境が正しく動作することを確認します。また、監視ツールも計画通り導入し、きちんとログ・メトリクス・トレースを取得・可視化できることを確認します。

負荷クライアント環境構築

負荷テストの対象となるアプリケーションを、計画した通りにテスト用の環境に構築していきます。前回の記事で説明した通り、「負荷テスト環境専用に AWS アカウントを作成し、本番同等のスケールで環境を構築する」というのがベストプラクティスです。IaC などを活用して負荷テスト用の環境を立ち上げ、必要に応じて外部接続先のスタブなども構築していきます。疎通確認を行い、環境が正しく動作することを確認します。また、監視ツールも計画通り導入し、きちんとログ・メトリクス・トレースを取得・可視化できることを確認します。

負荷クライアント環境構築

AWS上で分散テスト環境をCloudFormationでデプロイするための手順を日本語で説明した図です。ステップごとにAWSコンソールでの操作や入力項目、およびボタンのクリック方法が示されています。

負荷ツールの動作する環境を構築していきます。負荷テストの際にはクライアントがボトルネックにならないように注意する必要があるため、適切なスペックを持つコンピューティングリソース上で負荷ツールを実行する必要があります。コンピューティングリソースを立ち上げたのち、必要なツール (JMeter など) を導入します。クライアントがネックにならないようにスケールアウト可能な構成にしたいのであれば、そのための準備も必要になります。

DLT ソリューションを使う場合

今回の主役である DLT ソリューションであれば、CloudFormation スタックをデプロイするだけでこの環境構築が完了します。ソリューションのランディングページ から「AWS コンソールで起動する」をクリックすると、 AWS マネジメントコンソールの CloudFormation スタック作成画面に移動できます。ここで必要な設定を行ってデプロイするだけで、環境構築が完了します。

必要な設定も、以下の 3 つだけ (※1) となっています。

  • スタックをデプロイする AWS リージョンの選択

  • スタック名の設定 (任意の値で構いません)

  • DLT ソリューションのフロントエンドにログインするためのユーザ名とメールアドレス

ソリューションのランディングページ にアクセスし、下の画像の通りに手順を進めると、 7 ~ 10 分程度でソリューションのデプロイが完了します。

※1 他にも、ソリューションをデプロイする VPC について設定することができます。例えば、閉域内に構築されたシステムへの負荷テストを行いたい場合、VPC ピアリングなどで対象システムと通信可能な VPC を作成し、その VPC 内にソリューションをデプロイすることができます。

Screenshot of the Distributed Load Testing solution on AWS, showing the Test Scenarios dashboard with table columns for Name, Id, Description, Last Run (UTC), Status, Next Run (UTC), Recurrence, and Details. The message instructs the user to select Create test from the top menu to get started.

ソリューションの構築が完了すると、入力したメールアドレスに「Welcome to Distributed Load Testing」というタイトルのメールが届きます。

  • メールに記載されているリンクをクリック

  • メールに記載されたユーザー名・仮パスワードを入力

  • パスワードのリセットを求められるので、新しいパスワードを入力

という手順で、ソリューションのフロントエンド (以下、 DLT コンソールと呼びます) にログインすることができます。

DLT ソリューションの場合、負荷クライアントの構築作業はこれだけで完了となります。あとは負荷テストで用いるシナリオを作成し、ローカル環境などで疎通確認を行ったら、このコンソールからシナリオをアップロードして負荷量を調整するだけで負荷テストを実施することができます。

負荷シナリオ作成・疎通

負荷テストでは、実際のユーザの行動 (例 : ユーザーが EC サイトのトップページにアクセスして、商品を検索してカートに投入して、購入する) をシナリオとして模擬し、それをスクリプトに落とし込んでいきます。JMeter (および、JMeter を内部で利用する負荷ツール) で負荷テストを行う場合は、JMeter の GUI を利用してシナリオをスクリプト化していきます。 GatlingLocustk6 などのツールで負荷テストを行う場合は、それぞれのツールに沿ったプログラミング言語を用いてシナリオのスクリプトを作成します。

本記事ではシナリオ作成方法の詳細については取り扱いませんが、シナリオの作成にあたっては以下のような点に注意が必要です。

  • ユーザーの一連の行動で引き回されるパラメーター : セッション ID や Cookie の情報、認証トークンなど、どういったパラメーターがリクエスト間で引き継がれているのかを理解して、それをスクリプト上で再現する必要があります。

  • ユーザーごとに異なるパラメーター : 負荷テストにおいては、多数のユーザーが代わる代わるシステムを利用することを模擬的に実行していきます。たとえば、ユーザーを認証して処理を実行するようなシステムであれば、ユーザーごとにユーザー名とパスワードを入れ替えてリクエストを実行する必要があるでしょう。リクエストごとに異なる値を入力して実行する必要がある場合に、CSV にそういった情報を保存しておき、スクリプト内では 1 回 1 回のユーザのシナリオごとに CSV を 1 行読み込んでリクエストを実行させるような実装が必要となります。

  • ユーザーのシナリオごとの負荷量 : 前回の記事で説明した通り、負荷シナリオの検討にあたってシナリオごとの負荷量の比率などを決定していました。これを負荷スクリプト上でも再現する必要があります。

DLT ソリューションを使う場合

Screenshot of Apache JMeter test plan configuration in Japanese, showing distributed test setup and thread group properties for different test scenarios on AWS.

DLT ソリューションは内部で JMeter を利用しているため、シナリオも JMeter で (.jmx ファイル) 作成します。なお、単一 URL に対する簡易な負荷テストであれば、シナリオファイルを作成せずとも DLT コンソール上で URL と HTTP メソッド、ヘッダー、ペイロードのみを指定する形でテストを実行することも可能です。

JMeter の場合は、JMeter 自体をプロキシとして動作させた状態で、ブラウザ操作を行うことでシナリオを作成するレコーダー機能や、手動で HTTP リクエストの情報を JMeter 上で入力していくことでシナリオを作成する機能があります。

一般的には、まずはプロキシ機能を用いてリクエストをキャプチャしてシナリオのベースを作り、前述の観点 (ユーザーの一連の行動で引き回されるパラメーター / ユーザーごとに異なるパラメーター / ユーザのシナリオごとの負荷量) を考慮した修正を加えていく・・・という流れでスクリプトを作り上げていきます。

また、その中で必要な CSV ファイルなどがあれば、.jmx ファイルと一緒に作成していきます。DLT ソリューションでも、こういった外部ファイルの利用が可能となっています。

データ作成

前回の記事で紹介した通り、負荷テストを実施するうえで DB の状態 (データ量・カーディナリティ・ヒットデータ率) は重要なファクターとなります。負荷テストの目的として定義したシチュエーションにおける DB の状態になるよう、 DB 上のデータを作成していきます。

負荷テストで利用する外部システム (もしくはスタブ) や、シナリオで利用する CSV との整合性を取ってデータを作成する必要がある点に注意しましょう。

手順整備

負荷テストは、ショット (※2) ごとに準備→実行→分析→チューニングというサイクルを何度も回すことになるため、実施にあたっての手順をきちんと整備し、タスクの抜け漏れがないようにしておきましょう。特に、以下の点は注意が必要です。

  • データ状態整備 : 負荷テストに更新系リクエストを含む場合、試験ショットを実施することで DB の状態が書き換わります。毎回の試験実施条件を揃えるために、データの状態を毎回同じ状態に戻せるような手順を用意しておきましょう。(例 : Amazon Aurora で、Amazon S3 からテーブルにデータをインポートする)

  • キャッシュ状態整備 : 前回の記事で紹介したとおり、キャッシュの状態も性能に影響します。システムとして想定するキャッシュの状態があれば、それを毎回再現できるような手順を準備しておきましょう。(例 : Amazon RDS for PostgreSQL や Amazon Aurora PostgreSQL で、 pg_prewarm を用いて都度キャッシュを prewarm する)

  • 負荷クライアントログの収集・退避 : 負荷テストの結果の分析にあたっては、負荷クライアントのリクエストのログを出力することがあります。EC2 などで JMeter 等の負荷ツールを稼働させる場合、膨大なログが出力されてストレージを圧迫するケースがあるため、Amazon S3 等へのログの収集・退避を検討しておきましょう。なお、 DLT ソリューションで負荷テストを実施する場合、 ログファイルは Amazon S3 上に出力されるため、ログの容量について心配する必要がありません。

また、負荷テストのショットの条件・結果・証跡を管理するルールを決めておくことも重要です。例えば DLT ソリューションの場合、1 つのシナリオに基づく負荷テストのショットを負荷量 (タスク数・スレッド数) を変更して再実行し、実行条件や結果を一元的に管理する機能を有しています。が、各ショットでの考察やチューニング、実行の目的などまでは管理することができないため、これらを管理できるようなしくみを検討しておくとよいでしょう。

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

2. 負荷テストの実施でのタスク

2-1. 実施タスクの全体像

さて、準備ができたらいよいよ負荷テストの実施に入っていきます。負荷テストで最初からエラーなく目標性能を達成できるケースはまずないため、複数回のショットを繰り返します。第 1 回の記事でも簡単に記載しましたが、以下のことを繰り返しながら性能目標の達成や限界性能の計測を目指していきます。

  • ショット準備

    • ショット目的定義 : 同ショットで確認したいことを定義していきます (例 : ピーク比 50 % 性能が出せることの確認、前ショット後のチューニング効果の確認)。負荷テストは仮説立案と検証の繰り返しです。毎回必ず「今回のショットでは何を目的にしていて、そのためにどのような条件を変更して実行するのか」を明らかにしておきましょう。

    • 目的に応じた実施条件修正 : ショットの目的に応じて、負荷クライアントのスクリプトや負荷量を修正します。

      • DLT ソリューションでは、JMeter スクリプトの変更なしにタスク数やスレッド数で負荷量の調整が可能です。

    • 環境状態整備 : 前述の通り、更新系処理を含む負荷テストの場合、毎ショットの実施条件をそろえるためにデータの状態を戻す必要があります。キャッシュの状態なども必要に応じて戻していきます。

  • ショット実行 : 負荷クライアントからの負荷リクエストの実行を行います。実行中は、負荷クライアントやテスト対象アプリケーションが出力するリアルタイムのログ・メトリクスを確認して状況をチェックします。これは、シナリオのバグなど、何らかの問題があって続行が無意味・不可能と判断できた場合に中断できるようにするためです。

  • ショット分析 :

    • 性能指標分析 : スループット・レスポンスタイム・エラー発生有無を確認し、性能目標を満たしているかどうかを確認していきます。

      • DLT ソリューションは、スループットやレスポンスタイムを自動で可視化するダッシュボード機能も備えています。

    • ボトルネック分析 : アプリケーションのメトリクス・ログ・トレースから、ボトルネック箇所がどこにあるかを特定していきます。

  • チューニング : 目標性能未達の場合、 パラメータ変更やスケールアップ / アウト、アプリケーション改修などを実施することでこの改善を試みます。これが正しく効果を発揮するかを確認するために、再びショット実施サイクルを回していきます。

2-2 . DLT ソリューションを用いたテスト実施の流れ

ここからは、 DLT ソリューションを用いたテスト実施の流れを見ていきます。負荷クライアントに関係しない作業は個々のアプリケーションに依存するため、負荷クライアントを利用する部分に絞って説明していきます。

ショットの実行

JMeter で作成した負荷スクリプトを、 DLT コンソールからアップロードし、負荷テストを開始します。なお、.jmx ファイルのみを利用する場合は単体でアップロードすることもできますし、 CSV ファイルを利用したり、スクリプト内で利用するライブラリを jar ファイルとして利用する場合は、 .jmx ファイルと一緒に zip ファイル化してアップロードすることもできます。

Screenshot of the 'Create Load Test' screen for Distributed Load Testing on AWS, showing configuration for a JMeter scenario test, task count, concurrency, region, ramp up, hold duration, and file upload options.
  1. DLT コンソールの上部 「CREATE TEST」をクリックし、テスト作成画面に遷移します。

  2. 作成したシナリオをここでアップロードし、テストのパラメータを入力します。パラメータには、テストの名前や説明、負荷量 (タスク (コンテナ) 数とタスクあたりのスレッド数)、負荷実行時間などが含まれます。パラメータの詳細については、DLT ソリューション ワークショップ に説明を載せているのでご参照ください。

  3. RUN NOW」をクリックします。

Screenshot of a realtime metrics dashboard for distributed testing on AWS, showing response time, virtual users, successes, and failures for the ap-northeast-1 region. Includes scatter and line charts with a PAUSE button and a link to the Amazon CloudWatch Metrics Dashboard.

すると、これらのパラメータをもとに AWS Fargate 上でタスク (コンテナ) が立ち上がり、各タスク内で JMeter が起動して負荷テストが開始されます。また、CloudWatch ダッシュボードが作成されて DLT 上での結果が閲覧できるとともに、DLT コンソール上でもリアルタイムのメトリクスを閲覧することができます (図)。

ショットの分析

Screenshot of a distributed load testing dashboard on AWS, showing JMeter scenario test results including response times, latency, connection times, bandwidth, percentile response time, CloudWatch metrics graph, and results history.

指定した時間の負荷実行が完了すると、Fargate タスクが終了し、実行結果が集計されて DLT コンソール上に表示されるようになります。スループット・レスポンスタイム・エラー数の時系列での変化を確認することができ、目標性能を満たせていたかどうかを簡単に確認可能となっています。閲覧できる情報の詳細については、 DLT ソリューション ワークショップ に説明を載せているのでご参照ください。

なお、JMeter シナリオを用いたテストの結果画面では、JMeter スクリプト上で各リクエストに設定したラベルごとに各種メトリクスを確認することができます。そのため、どのリクエストで遅延やエラーが発生していたのかも簡単に確認できるようになっています。

目的に応じた実施条件修正と再実行

ショットを実行した結果、「今かけている負荷量であればアプリケーションの性能に問題がないため、さらに高い負荷をかけて性能の限界を見極めたい」というのが次のショットの目的になったとします。同じシナリオを用いて負荷量を増減するだけであれば、DLT コンソール上で簡単に実施条件を修正して再実行することができます。

過去ショットの実施結果画面で「EDIT」をクリックし、タスク数とタスク内のスレッド数を変更し、「RUN NOW」をクリックします。

これで、JMeter シナリオを変更することなく負荷量を変えたショットを簡単に実行することができます。

Screenshot of the Distributed Load Testing UI on AWS, displaying load test details for a JMeter scenario test with two thread groups. The test is completed, showing options to start, edit, or delete, and providing access to full test results and download links. Includes information about concurrency, ramp up, hold duration, and test region.

Screenshot of the 'Update Load Test' interface for distributed load testing on AWS, showing configuration settings for a JMeter scenario with two thread groups. The form displays fields for name, description, task count (5), concurrency (20), AWS region, ramp up and hold times, as well as options to run the test immediately or on schedule.

このように、DLT ソリューションは負荷テストの準備と実行を省力化するのに役立つ様々な機能を提供しています。

2-3. チューニングのサイクル

AWS上で分散システムの負荷テストを実施した際のボトルネックやスループットの変化を示す説明図。チューニング前後の各構成要素(負荷クライアント、ALB、Webサーバ、APサーバ、Aurora)のスループットの推移とボトルネックの遷移が日本語で解説されている。

さて、ここからは再び負荷テストの一般論に戻り、負荷テスト実施におけるチューニングのサイクルについて述べていきます。

負荷テストにおいて、目標とする性能が出せていない場合、「どこかのコンポーネントに性能不足の箇所があり、ボトルネックになっている」と言えます。例えば下図の上部のように Web 3 層構造のアプリケーションで考えると、負荷クライアント・LB ・Web サーバー・ AP サーバー・ DB サーバーのいずれかの最大スループットが低いことにより、アプリケーション全体のスループットが一番低いスループットに束縛されることになります。アプリケーション上でログ・メトリクス・トレースを利用してボトルネック箇所を特定し、チューニングすることでこのボトルネックを解消することができます。

さて、ボトルネックを無事解決できたあと、次に起きることはなんでしょうか ? それは「元のボトルネックの次にスループットが低い要素が次のボトルネックになる」という事象です。目標性能を満たすまで、このボトルネック発見とチューニングを繰り返していくのが負荷テストです。

負荷テストで注意すべき点として、負荷クライアントがボトルネックになることもあるという点が挙げられます。ですが、DLT ソリューションを負荷クライアントとして利用していれば、負荷タスク数を増加させることでこの対処も容易に行うことができます。

チューニングを行う際の注意点についても触れておきます。それは、チューニングのためにパラメータ等を変更する際にはメリットだけでなくリスクも検討すべきということです。多くのチューニングは何かしらのトレードオフを伴うため、チューニング内容を多面的に検討しておくようにしましょう。

例)

  • 大量の DB レコードを処理するバッチ処理の遅延に対処するため、処理時間短縮のために DB フェッチサイズを引き上げたら AP が OutOfMemory を引き起こしてしまった

  • Web 3 層システムで、AP サーバーでの DB コネクション取得待ちの対処のためにコネクション数を増やしたら、 DB がメモリ不足でハングしてしまった

3. 負荷テストの評価でのタスク

負荷テストを実施し、目標性能までのチューニングが完了した後のタスクについても説明していきます。

試験実施結果の取りまとめ

負荷テストの結果と考察は、ドキュメントとしてどこかに残しておくのがよいでしょう。将来もし本番環境で性能トラブルが発生した場合に、過去の負荷テストでの傾向がその分析に活かせる可能性があります。

チューニング内容の取りまとめ

負荷テスト前に比べて、チューニングとしていくつものパラメータが変更されていることは往々にしてあります。チューニング内容を開発・本番に取り込むために、チューニング内容を整理します。また、今後の知識の横展開という意味でも取りまとめておくことは重要です。

Next Action の検討

性能試験結果を踏まえて、重点的に監視すべきポイント、スケーリング関連の対応方法、性能限界を超えた負荷が発生した際にシステムを守るための対処などを Nect Action として検討します。

前回の記事の最初で性能試験の種類について説明しましたが、そこで「限界性能試験で、負荷量を 120 %、140 %、etc・・・といった形で増大させ、システムが応答できなくなる負荷量を確認する」ということをお伝えしました。この際に重要なのは、

  • システムが応答できなくなるレベルの負荷が発生したときに、どこがボトルネックになるか

  • システムが応答できなくなるレベルの負荷が発生したときにどういった対策を取ればよいか

  • システムが応答できなくなるレベルの負荷が発生したこと / しそうなことをどのように検知すればよいか

の洞察を得ることです。例えば、以下のようなアクションプランをビジネスサイドと合意することができます。

  • 限界性能試験の結果、 目標性能の〇〇〇 % の負荷が発生した場合、 〇〇〇がボトルネックとなり性能劣化を引き起こす 

  • その際、〇〇というメトリクスが 同事象の発生可能性を検知するのに適切である

  • そのため、同メトリクスは重点的に監視し、 〇〇を超えた時点で警戒、〇〇を超えたら流量制御により新規訪問者の流入を制限し、 利用中のユーザの購買行動の完遂が妨げられないようにする

まとめ

本シリーズでは、DLT ソリューションをご活用いただくために役立つ負荷テスト全般の知識を、全 3 回にわたってお伝えしてきました。DLT ソリューションに限らず、 AWS の様々なメリット・機能を負荷テストで活用できることもお伝えできたのではないかと思います。

本シリーズは DLT ソリューションそのもの以上に負荷テスト全般についてお伝えする形となりましたが、これとは別に DLT ソリューションを用いた負荷テストを体験できる ワークショップコンテンツ を公開しました。DLT ソリューションをデプロイし、負荷テスト対象のサンプルアプリをデプロイしたのち、同ソリューションを用いて実際に負荷テストを実施していく内容になっています。コストは 1 USD〜数 USD、時間としては 2 ~ 3 時間程度で完了できるものとなっています。
今回の記事シリーズで負荷テストに興味を持った方、負荷テストによいツールをお探しの方は、是非ともお試しください。詳細はこちら »

それではみなさま、Happy Load Testing !

筆者プロフィール

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

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

A musician is performing on stage, playing a bass guitar under stage lights with a microphone nearby.