クラウド時代の負荷試験・性能試験を考える

 Amazon Web Service、Google Cloud Platformに代表されるクラウドサービスは、今や無くてはならないものとなっています。

 そんなクラウド時代の負荷試験・性能試験について考えてみます。

はじめに

 負荷試験、および性能試験は、インフラストラクチャが十分な性能を備えていることを保証する試験です。

 オンプレミス時代は、この負荷試験、性能試験は非常に重要でした。アプリケーションをリリースしてから性能が足りないことが発覚しても、すぐに機器を調達してスケールアップしたりスケールアウトしたりということが出来いからです。

 キャパシティプランニングと併せて、これらの試験は最初期に設計され、計画的に実行されてきました。

クラウドでは

 ところが、クラウドを利用したインフラストラクチャは、サーバーの調達を待たずして、設定ひとつで性能を上げたり、台数を増やしたりすることができるようになったため、厳格な負荷試験、性能試験は以前に比べて必要なくなりました。

 つまり、負荷試験や性能試験の必要性が著しく下がっているわけです。しかし、全く意義が無いわけではありません。

テストで何を調べたいかを明確化する

 オンプレミス時代は、キャパシティプランニングに基づいた同時接続数や、利用者数を想定して負荷を加え、システムが問題なく動作することを確認するのが主な目的でした。

 しかし、現代においては、多くのクラウドでサポートされているオートスケールという仕組みにより、キャパシティプランニングをそれほど意識しなくてもよくなりました。なにせ、利用者数が増加して負荷が高まると、勝手にインスタンスが立ち上がって自動的にスケールアウトしてしまうわけです。

 ただ、そんなクラウドを利用している場合でも負荷試験が全く必要ないわけではなく、様々な理由によって行うことがあります。

スケールアップ・スケールダウンで問題が起こらないか

 スケールの処理はクラウドサービスによって様々ですが、たとえばオートスケールしたときに各サーバーがしっかり動作するかをリリース前に確認する価値はあります。

 具体的には、以下のような問題が考えられます。

  • コネクションプールの設定が正しくなく、スケールしたときに相手先のコネクションを食いつぶしてしまった
  • 設定・設計にミスがあって、新しいインスタンスが正しく動作しない状態になっていた

 このうち、スケールに直接的な問題があるとすれば、コネクションプールの問題です。これは、想定される利用者数に応じたインスタンス数を手動で起動させることによって容易に確認できます。
 反面、設定の不備については、実際に負荷を掛けてみるまでわかりません。

 実際には、インスタンス数を上げて通常の試験を走らせるだけでも、大半のことは確認できます。あえて負荷試験を実施する必要は無いかもしれませんが、万全を期すためにはやりすぎということはありません。

急激な負荷の増大に耐えられるか

 ユーザー数が、徐々にではなく急激に増える可能性がある場合、それをシミュレートした負荷試験を行うことは十分に意義があります。オートスケールの仕組みを利用する場合、インスタンスが立ち上がるまでに少しの時間が掛かります。

 このとき、インスタンスが立ち上がるまでの間、503などの好ましくないエラーを返すことになるかもしれません。サービスの信頼性を確保できなくなりますから、これは無視できない問題です。

 初期インスタンス数を正しく計画したり、時間ごとで事前にスケールするなどで問題を回避することができますが、それが正しく動作するかを確かめるという意味では、全く意味が無いことではありません。急激な負荷の増大に耐えられない、という事実さえ知っていれば、対策はいくらでもあるわけですから、試験は重要になってきます。

パフォーマンスが落ちないか

 サービスのスケールを正しく設計していない場合、パフォーマンスが落ちたり、意図しない動きをするかもしれません。

 例えば、セッション情報をどこか重めの(速度の遅い)サーバーに保管しておくことにします。このサーバーはレスポンスが遅く、リクエストを捌くのに3秒程度掛かってしまいます。しかし、セッションはサービス側でキャッシュされる仕組みを持つ設計にしたため、少数のインスタンスでは快適に動作するように見えます。

 しかし、その後利用者が爆発的に増え、インスタンス数が100台程度に増えたとします。これは喜ばしいことですが、セッション情報が思うようにキャッシュされないため、リクエスト毎に3秒かかるようになってしまいました。

 結果、利用者に過度なストレスを与えてしまい、多くの解約を生んでしまった・・・。

 というシナリオが考えられます。設計段階で発見できるものですが、見落としがないかを確認する上でも負荷試験を行うことが大切です。

クラウドに対する負荷試験を行う必要性

 結論から言えば、目的とコストの兼ね合いであると言えます。負荷試験は確かに重要で、やったほうがいいのは明確なのですが、他に優先すべきこともたくさんあるはずです。

 信頼性が重要なシステムでは、クラウドであったとしても、実際に即したシミュレート試験を行うことは大切ですから、コストを掛けてでも実施したほうがよいでしょう。反面、スタートアップなどでは、お金と時間の両方が無いことが多いです。サービスを一刻も早くリリースしなければならないし、人を雇う余力もない、ということが珍しくありません。

 こういったとき、サービスの方向性を加味し、どこまで信頼性を上げるべきかを見極め、ビジネス的な判断を行うことが大切です。闇雲に負荷試験を実施しては商機を失うかもしれないし、資力が枯渇して倒産ということになれば目も当てられません。

 そういった意味では、実際にユーザーの動きを模倣した負荷試験は、重要ではあるが必須ではない、と言えるでしょう。少なくとも、単体試験や結合試験に優先して行うべきことでは無いのかもしれません。

 しかし逆に、当初から相当数の利用が見込まれる場合は、負荷試験は非常に重要なファクターと言ってよいでしょう。ソーシャルゲームでは秒間に数百万回以上のリクエストを捌くことになりますが、ここの試験が行われていない場合、サーバーが落ちて長期メンテナンスという憂き目に会うかもしれません。これはサービスの信頼を貶める重大事故ですから、リスクとしては受容できないという判断を下すことになります。

テストポリシーについて

 大半のクラウドサービスでは、負荷試験に対するテストポリシーがあります。事前申請を必要としているサービスもありますので、必ず事前に確認してください。

負荷テストツール

 オンプレミス時代を殆ど同じ手法で問題ありませんが、最近の便利なテストツールについて触れておきます。

Load Impact

 Load Impact

 負荷試験用のクラウドサービスです。お金を掛けられるなら最適かもしれません。そうでなくても、テスト専用のサーバーやインスタンスを用意しなくてもすぐに実行できる点や、k6を用いてリーダブルなテストスクリプトが書ける点は評価すべきでしょう。将来サービスの規模が大きくなったときにも、容易に負荷テストを行うことができますね。

 反面、そこまでの機能が必要ないんだけど・・・という場合は、別の手段を考えてもいいかもしれません。

Vegeta

 Vegeta

 コマンドラインベースで手軽に利用できます。複雑なシナリオを要さない、シンプルな負荷試験には最適ですが、スクリプトを組むことで複雑なシナリオにも対応できそうです。

 分散して負荷を掛けるような作業は少し工夫が必要になりそうですが、そう複雑な手順を踏まなければならない、というわけでもなさそうです。

 手軽に負荷試験を回すには有力な手段です。

Locust

 Locust

 pythonの負荷試験ライブラリです。大規模な負荷試験には必須の分散実行もサポートしているため、不満なく試験を回すことができます。

Apache Jmeter

 Apache JMeter

 昔からのデファクトスタンダード的な存在であるJmeter。GUIがあり、Java用のAPIも用意されているため、手軽に使うには丁度いいかもしれません。しかし、セットアップや実行が少し面倒なこともあり、最近の流れにはそぐわないツールになりつつあります。

まとめ

 クラウドサービスの台頭により、負荷試験を行う必要性も薄まってきましたが、まだまだそれらを行う意味はありますし、それによって得るものも大きいはずです。

 余力があるなら、是非やっておきたい試験ですね。