クラウド ロード テスト サービスがハイパースケールに対応: 100 万ユーザーの同時実行負荷を生成する場合

本記事は、マイクロソフト本社の Microsoft Application Lifecycle Management の記事を抄訳したものです。 【元記事】 Cloud-load testing service is hyper-scale ready: lessons from generating 1M concurrent user load 2016/9/30

 

販促キャンペーンやクリスマス セールといった大規模な季節イベントの最中に、基幹業務アプリがダウンしてしまったという話はよく耳にします。このような場合、原因の多くは、一時的に発生する大規模な需要にアプリが対応できていないことにあります。最終的にはサーバーで障害が発生して、顧客満足度の低下や機会損失といった最悪の事態につながることになります。お客様のアプリがこのような事態に陥らないようにするには、クラウド ロード テスト (CLT) サービスを使ってアプリが需要の急増に対応できるかどうか検証するのがおすすめです。

ロード テストに使用するツールやサービスでは、必要な規模の負荷を生成できなくてはなりません。そのため、マイクロソフトでは先日インフラストラクチャを変更し、CLT サービスをハイパースケールで実行できるようにしました。ハイパースケールへの対応状況を検証する一環として、100 万ユーザーの同時実行負荷を生成するテストを実行し、正常に行えることを確認しました。「同時実行」とは、100 万ユーザーが全員同時にアクティブな状態にあったということです。このテストは、自動的にプロビジョニングされたエージェントを使用する場合と、Azure IaaS VM を使用して「自社のサブスクリプションを持ち込む (英語)」場合の両方に対応しています。つまり、自動的にプロビジョニングされたエージェントを使用するにしても、自社のマシンを持ち込むにしても、ハイパースケールでテストを実行できます。

先日実施したインフラストラクチャの変更によってさまざまな効果が表れていますが、ここでは特に以下の 2 点にご注目ください。

  • エージェント コア 1 つあたりの仮想ユーザー数が、最大でこれまでの 2.5 倍に増加しました。これまで宣言型 Web テストではエージェント コア 1 つにつき 250 ~ 1,000 の仮想ユーザーを生成できましたが、この数が 600 ~ 2,500 に増えました。
  • リソース取得の総所要時間が 50% 以上短縮され、ロード テストでエージェントを準備してテストを開始するまでにかかる時間が大幅に短くなりました。大規模なテストを実行する場合、これまでは準備に 15 分程度かかっていましたが、これが 7 分程度にまで短縮されます。また、リソース保持機能 (英語) も引き続き使用できるため、ロード テストで修正とテストを短期間で繰り返す場合はさらに準備時間を削減できます。

以降では、大規模なロード テストの実行に関する疑問にお答えします。また、意図した負荷を適切に生成できるように、負荷の生成方法に影響を及ぼす設定についてもご説明します。

まず、私たちが実行したテストのスクリーンショットをご覧ください。

1MTest

ご覧のとおり、同時実行ユーザー数 100 万、総要求数 4,370 万、秒間要求数 7 万 1,100 という生成結果と、エラー発生数 0 という非常に良好な結果が得られました。それでは詳しくご説明していきます。

アプリのセットアップ: このテストの目的は 100 万の同時実行ユーザーを生成できるかどうかの検証であったため、容易にスケーリングできるアプリが必要でした。このため、コアの検証のほか、サービスの問題を修正して、安心してアプリをスケーリングできるようにすることに集中しました。テストではシンプルな ASP.NET Web API コメント アプリ (英語) を使用し、1 台のロード バランサーに接続された Azure IaaS VM 一式にそれをデプロイしました。徐々に負荷を増大させながらテストを実行し、アプリがその限界に達すると VM インスタンスをさらに追加して増強しました。100 万の同時実行ユーザーに対してアプリからサービスを提供するために、Azure の Standard_D4_V2 VM インスタンスを 12 台使用しました。

テスト: ホーム ページへの要求を送信する Web テストの作成には Visual Studio を使用しました。一定の負荷パターンを用いるようにロード テストを設定し、100 万の同時実行ユーザーをシミュレートしました。通常、現実世界では一定期間にわたって負荷が上昇します。しかし、エージェントが過酷な条件も簡単にシミュレートできることを検証するために、このテストでは大規模で一貫した負荷をかけました。テストの詳細は GitHub (英語) で公開しています。

ロード テストに関して、「1 台のエージェントでどのくらいの数の仮想ユーザーを生成できるのか?」、「ロード テストで必要となるエージェント数は?」といった質問をよくいただきます。皆様が特に関心のある質問だとは思いますが、これには「場合によって異なる」としかお答えできません。アプリは 1 つひとつが違い、ユーザーのシナリオをシミュレートするテストもそれぞれ異なります。宣言型の Web テストであるのか、コードを作成して実行する単体テストであるのか、または検証するシナリオを的確に再現した自作コードによる Web テストであるのかによっても異なります。さらに、テストでカスタム プラグインを使用する場合もあります。テスト実行時には、エージェントは負荷を生成するために CPU やメモリ、ディスクなどのリソースを消費します。テスト エージェントのこれらのリソースについては、ロード テスト中にパフォーマンス カウンターのデータが収集されるため、これを基にエージェントでさらに多くの仮想ユーザーを処理できるかどうかを判断できます。まずは小規模なロード テストから始め、大規模なロード テストを実行する前にそのテストでのエージェントの処理能力を把握することをお勧めします。

TCPV4

 

上のスクリーンショットは、エージェントで収集される各種のパフォーマンス カウンターを示したものです。これらの値はテストで消費される各種リソースの状態を表し、テストに使用するエージェントの能力を判断する際の参考になります。CPU やメモリなどの通常の指標に加えて、私たちのテストでは TCPv4 カウンターのデータも収集しています。この値はハイパースケールでテストを実行する場合に重要です。ロード テストを実行しアプリに要求を送信するとき、接続にはソケットが使用されます。要求で SocketExceptions エラーが発生した場合、アプリが負荷を処理できなかったために接続が切断されたのか、エージェントがソケットの能力の限界に達したのかを簡単に判断できる方法があると便利です。なお、エージェント マシンは 1 台で最大 64,000 の接続が可能です。

1 仮想ユーザーあたりの最大接続数に影響を及ぼす要素と、ロード エージェントを最大限に活用できる設定については、“WebTest 接続モデル” の設定が関係してきます。この設定では、Web テストの実行を含むロード テストでの接続の使用方法を制御します。

ユーザーあたりの接続” モデルは、ブラウザーを使用しているユーザーの動作を近似したシミュレーションです。まず、Web パフォーマンス テストで最初の要求が発行されたときに最初の接続が確立されます。ページに複数の依存要求が含まれている場合は、さらに接続が追加されます。これらの要求は、追加された接続を使用して並列的に発行されます。ブラウザーの動作に近づけるために、最大で 6 つの接続が同時に確立されます。このモデルで負荷を生成すると、エージェントの接続数が増加し (ユーザー負荷数の最大 6 倍)、生成可能なユーザー負荷が制限されるという難点があります。また、接続に関係するメモリ使用量も増加し、1 つの Web テストが完了して次の Web テストが新たに開始されるときの接続の切断と再接続に要する処理時間が長くなります。ユーザー負荷を高める場合は、“接続プール” モデルを使用することをお勧めします。

接続プール” モデルでは、複数の仮想ユーザーで Web サーバーとの接続を共有するため、ロード テスト エージェントのリソース消費が抑えられます。ユーザー負荷が接続プール サイズを超過する場合、異なる仮想ユーザーで実行されている Web パフォーマンス間で接続が共有されます。このため、ある Web テストが接続を使用しているとき、別の Web テストは要求を発行する前に待機しなくてはならなくなる可能性があります。Web パフォーマンス テストで要求が送信されるまでの平均待機時間は、ロード テストの平均接続待機時間を示すパフォーマンス カウンターで追跡されます。この値は、ページの平均応答時間を下回る必要があります。要求の平均接続待機時間がページの平均応答時間を上回る場合は、接続プール サイズが小さすぎてページのスループットが限界に達していると考えられます。適切な接続プール サイズは次の式で求められます。

接続プール サイズ = 64,000 / (最大同時接続数 (テストで依存要求が発行される場合、この値は 6) * サーバー URI ホスト数)

要求に対して CDN からサービスが提供される場合、それに応じてサーバー URI ホスト数を調整する必要があります。

プール サイズを決定するには、ロード テストで使用する Web テストをローカルで実行し、その結果から依存要求の有無とサーバー URI ホスト数を確認します。これは、JavaScript、CSS、画像などの依存要求のほとんどがテスト作成時に記録されないためです。その代わりに応答の内容が解析され、その内容に応じて追加の要求がテスト実行時に発行されます。このため、作成されたテストに依存要求が記録されなくても実際には存在している可能性があり、実行結果を確認しなければ判断できません。ここからは、その例を見ていきます。

bingtestresult

 

このスクリーンショットは、bing.com に要求を発行する Web テストの結果を示したものです。結果からわかるように、追加の要求は生成されていません (bing.com への 2 つ目の要求は 302 リダイレクトによるもので、依存要求ではありません)。また、要求先のサーバー URI も bing.com のみとなっています。テストでは他の要求がまったく発行されておらず、調査が必要な依存要求がないことがわかるため、最大同時接続数 = 1 (依存要求は存在しない)、サーバー URI ホスト数 = 1 (bing.com) になります。これにより、プール サイズは最大接続数の 64,000 とします。

 

 

 

 

 

 

dependentreqresult

2 つ目の例でも、1 つのトップ レベル要求を Azure Web サイトに発行しています。その結果、複数の依存要求 (画像や CSS など) が確認されましたが、そのすべてが単一サーバー ホストから提供されています。このため、最大同時接続数 = 6、サーバー URI ホスト数 = 1、そしてプール サイズは 10,667 となります。

同様に、CDN からサービスを提供される依存要求が存在する場合は、サーバー URI ホスト数が増加し、それに応じてプール サイズも調整が必要となります。

以上のことから、大規模なロード テストを実施する場合、プール サイズの値が小さいほど、大規模な負荷を生成するために必要なエージェントの数は多くなります。上記のテストでは 8 コアのエージェントを 20 台、合計 160 個のコアを使用して必要な負荷を生成しました。既定では、すべての VSTS アカウントで最大 200 コアのテストを実行できます。ほとんどの場合、これでお客様のニーズに対応可能であることを確認しています。さらに大規模なロード テストを実行する必要があり、エージェントのコア数が不足する場合は、vsoloadtest@microsoft.com までお問い合わせください。

最後に、問題発生時のトラブルシューティングを考慮すると、ロード テスト実行時にアプリを監視することも非常に重要です。アプリの監視には Application Insights などのツールをご利用ください。

この記事が皆様のお役に立てば幸いです。CLT でお客様のアプリに成果が見られた場合はぜひお知らせください。CLT サービスのハイパースケール対応状況の検証は、Visual Studio ロード テスト製品チームと Microsoft Testing Services チームが共同で実施しました。この取り組みに協力してくれた Dindo Sabale、Shyamjith Pillai、Dennis Bass に感謝の意を表します。アプリケーションのテストに関するコンサルティング サービスをお求めの場合は、srginfo@microsoft.com までお問い合わせください。Testing Services チームの業務は Microsoft Enterprise Services (英語) の一部であり、機能、パフォーマンス、テスト戦略、知識の提供、一般的なコンサルティングなど、テストに関するあらゆる点についてお客様を支援することに主眼を置いています。

いつものお願いではありますが、ロード テストに関するフィードバックやご質問をお待ちしております。お気軽に vsoloadtest@microsoft.com までお寄せください。