WEBサーバーパフォーマンスチューニング・どんなサーバーを選ぶ?~トラフィック制限について~

  • このエントリーをはてなブックマークに追加

先般このようなお客様のご用命がありました。

とある教育施設で、1年間のカリキュラムを提供する中心プラットフォームとしてWEBを利用し、ドリルのようなものを生徒に提示し、生徒各人でそのシステムを使って学習していただくシステムを開発しました。
1年間で利用する生徒は約50名。授業初日と最終日のテストでは、同時に50人以上が接続する可能性があります。
そのような条件で最適なサーバーマシンの構築と、WEBサーバーのパフォーマンスチューニングをお願いできますか?

最適なサーバー選び

ヘッドライン

まず、上記の条件をかなえるサーバーはどのようなものがいいのか。。。そこから考えなければいけません。
コンテンツ自体の容量も現状ではまだはっきりと見えておらず、わかる数字は同時に50人前後が接続する可能性があるが、それは1年間のうち、数回(数日)だけであるということのみです。
かかってくるであろう負荷も、トラフィック量もなにもかも、先方も初めてで、はっきりとしたことがまだわからないという要件でした。しかしながらこの状態だったとしても、サーバーは何かしら準備をして、コンテンツを展開していかなければいけない段階でした。

クラウドサービスを考えてみる

1年のうち、何回かのみ高負荷になるという条件だけはわかっていたので、通常時は最小構成、ピーク時にピークに合わせてリソースを増やすことができれば一番コストパフォーマンスが良くなるはずではないかと推測し、今回はクラウドサービスを提案いたしました。

今回はGMOクラウドのALTUS(アルタス)をチョイス。
理由は、仮想マシンの立ち上げが容易であること、1時間単位でのリソース割り当てが可能なこと、PleskコントロールパネルをGMO内でライセンス購入し導入できることの三点から選びました。
先方様ももともとPleskユーザですので、Pleskがあれば最悪自分たちで再起動処理などできるので入れておきたいということでした。

※クラウドサービスの利用価値

ALTUSに代表されるようなIaaS型クラウドサービスというのは、

  • 新規でのサーバー作成・契約などがシンプルかつスムーズ
    • サーバー構築自身が自動化されていることが多いので24h/365daysいつでも作ることができる
  • リソースの増減も機械化されていることが多いので、リアルタイムにリソースの増減を行うことが可能
  • サーバー自身のリソースも自由度が高く、最小構成/最大構成を自分で決めることができる
  • リソース自身の増減が自由でライブタイムでできるものが多いため、結果コストパフォーマンスに優れる

といったような特徴があります。
簡単に言えば、リソースは決め決めで、356days同じリソースで十分というサーバーなら、あらかじめリソースなどが決まっているVPSサービスのような、ある程度型にはまったサービスの方がコスパはいいでしょう。
今回の案件のようにピーク時はリソース(とくにCPUやメモリ)は、いくらでも必要だが、それ以外はミニマムでもお釣りがある。。。みたいな、負荷に大きな波があるような場合には、IaaS型クラウドサーバーは非常にコスパが良くなります。
どのようなときに使いやすいのかといいますと、例えば、【ライブやコンサートなどのチケット販売サイト】のようなものです。
有名なアーティストや、人気のイベントチケットなどは、販売から数分~1時間程度が勝負で、ものの1時間で完売してしまうようなケースが非常に多いものです。
そのような場合、1時間(余裕を見て前後数時間)だけリソースを大幅に増やして対応し、普段そのようなアクセスが集中しそうなチケット販売がない時は、ほとんどアクセスもなく(通常運用程度のアクセス)。。。というケースが多いものです。
この案件を、インフラ屋さんに固定のサーバーを導入したいと相談した場合、調達するマシンスペックは、ピーク時の負荷状況から逆算してマシンを調達することになりますから、、通常運用時に必要なスペックの数百倍~数千倍の処理をさばけるスペックになります。価格ももちろん数倍~数百倍になるのは目に見えています。
このような負荷に大きな波があるようなものに対してクラウドサービスは激烈なコストパフォーマンスを生み出します。

GMOクラウドALTUSのメリットとデメリット

やはりメリット、デメリット両方あるものです。パッと思いつくものを列挙しておきたいと思います。

メリット
  • ベースパッケージの導入数でリソースの大小を決めることができる
  • メモリとCPU、HDD容量については個別でリソース割り当てで増減させることができる
  • Pleskをオプションとして容易に導入できる
  • 転送料が基本無制限無料である
  • クラウド管理パネルがAWSより簡単で容易
  • 増量リソースは1時間単位の課金

等があります。
Pleskが簡単に導入できるのは今回大きかったですね。

デメリット
  • リソースの増減のたびにマシンごとの再起動を必要とする
  • HDDの増量は自らコマンドラインで増量分をマウントする必要がある
  • コアパッケージリソースは基本1か月単位の課金
  • よくよく調べると、上位ネットワークにポリシー不明のファイアウォールが張られている
    • ある程度自分で設定を見直して編集しないとまともに通信できない可能性あり

等ありました。
特に最後のファイアウォールについては最初のうち存在に気づかなくて、通信ができないできないと悩んでしまいました。
存在していることがわかれば、自分たちにとって最適なポリシーに変更することで問題は解決しますが、たどり着くためのマニュアルも膨大でかつ複雑になっているので見つけるのに苦労します。

想定負荷からどのくらいのリソースが必要か推し量る

想定される瞬間最大同時アクセスが50人という規模感がこの時点ではまだいまいちわかりませんでしたが、クラウドサービスで最小構成のマシンを構築し、リソースの増減を何度か繰り返しながら、同時アクセス50人という状況を作り上げベンチマークテストを行えば大体の負荷状況などの推測はつくと思いました。よって、今回はリソースが固定のVPSサービスより多少割高ではありますが、クラウドサービスを選択しました。

ベンチマークテストを行ってみる

さて、サーバーマシンをクラウドサービスを使って構築することは決まりましたが、それ以外のことはまだまだ何も決まっていません。
大きく決めなければいけないことは2点

  • 通常時の最低限のリソース
  • ピーク時の最大のリソース

の2つです。この両方とも、先方からはピーク時に最低5秒以内に表示できればOKです。という、ずいぶん緩い目標をいただいていましたが、私たちの方ではその5秒をなんとか2秒未満には通信が終了するという目標を設定し、リソースと、チューニング設定を見定めることにしました。

通常時のリソースについて

答えを先に言うと、通常時もマシンの付加的には1コアパッケージ(ALTUS内で最小構成のパッケージ)で十分なパフォーマンスを出せました。20人程度の同時接続でも1秒以内に表示するレベルです。
しかしながら1コアパッケージではHDD容量が少し心もとないので今回は2コアパッケージを採用しました。コンテンツ量と、ログファイルの保存を考えると少し少ないという感じでした。
これは、リソース追加で※HDDを増やし、1ヵ月維持するより、2コアパッケージにした方が安上がるからです。
また、2コアパッケージ程度なら、大きなVPSのプランを契約するよりよほど安いくらいです。

※GMOのALTUSは、HDDを容量追加しただけでは追加分を利用できません。Linuxシステム上で、マウントし拡張する必要があります。

ピーク時のリソースについて

こちらについては、ベンチマークテストを行いながら最適なリソース幅を見つけ出す必要がありますが、結論から言うと、CPUコア数を10前後、メモリを20GBをリソース追加、1日だけリソースを増やすとした場合に、1日あたりのリソース追加分の費用は数百円でした。
なので、今回は1年のうち1~3回程度だけということなので、リソースの追加は上限まで行くこととしました。それでも年間数百円~数千円レベルの追加料金です。

ベンチマークテストを実際に行ってみる

今回は、様々な事情があり(Pleskと、トラフィック制限の関係から。後述します。)ApacheをWEBサーバーとしますので、ApacheBenchというベンチマークツールを使ってテストを行いました。
どのようなテストを行ったかといいますと、同時アクセスを10~100同時アクセス×100回~1000回(繰り返す)というテストを行いながら、実際に自分たちも同時にそのWEBサイトにアクセスして体感速度を見ながら落としどころのWEBサーバー設定を探すというのをやりました。最適な結果を導き出すのに1週間程度要しました。(ApacheBenchの使い方と、ALTUSの使い勝手がわからなくて少し手間どってしまいました。)

設定はノーマルのままでリソースの増減によるチェック

DBを中心に負荷状況を確認しながらチューニング

当初ボトルネックは、WEBサーバーとDBになるだろうとあたりを付けていました。
DBにかかる負荷はWEBサーバーにかかる負荷より大きいだろうとも思っていました。
そうなってくると、単純にこちらからで行えることは、DBに使うことができるメモリを増やし処理をスムーズに行わせることだと思っていました。
それを念頭に、まずはサーバーがデフォルト状態のままベンチマークテスト。こちらが基準値になります。
さすがに同時アクセス50くらいになると、下手をしたら10秒くらいかかってしまいます。
いわゆるサイトが重い状態です。
ということで、メモリを徐々に増やしてテストしてみました。
しかし、設定をまったくいじらない状態でメモリやCPUを増やしたところで何も変化が起きません。
これでわかることは【リソースを増やしてもチューニングしなければパフォーマンスは変わらない】ということです。

DBへのメモリ割り当てを増やしてみる

DBサーバー自身で利用することが可能なメモリ量を設定してみます。
私の推測であれば多少なりともパフォーマンスが改善するはずです。
が、残念なことに、ほとんど何も変わりませんでした。
よって、ボトルネックはほかにあるということがわかりました。

WEBサーバーの設定・チューニングを確認

DBの方にメモリを割り当ててもあまり思ったよう軽くなっていきませんでした。
その時点で考えられるのは、

  1. そもそも全体のメモリが全く足りていない
  2. 別の部分がボトルネック

の2つではないかと思います。
1番のそもそもメモリが足りないという件については初期値2GB→拡張後22GBで、パフォーマンスが変わらない時点でメモリが足りないという推測ははずれだと思いました。
さらに、同時アクセス50という数字は、20GBメモリで捌けない量ではないと思うからです。
2番の別の場所がボトルネックではないか?という推測の方がまだ理に適っている気がしました。

今回の場合、DB以外でボトルネックになりそうなのはWEBサーバー、あとは、今回のソフトはPHPで作られているのでPHPの設定も可能性は0ではないなと思いました。
一応、この時点でnginxでベンチマークテストを行ってみましたが、パフォーマンス自体はほとんど変わりませんでした。

さて、そんなことを考えながらDB以外で、一番シンプルに考えればWEBサーバーのチューニングでボトルネックが解消される可能性は大いにあると思いましたのでWEBサーバーのチューニングを始めます。

と、行っても初期設定段階では、ApacheのKeepAliveがOFFだったのでONにしてみるくらいしか現状では思いつかなかったので、設定をしてみました。
そうしましたところ少しパフォーマンス改善したようで、10秒くらいかかっていたものが6秒くらいになりました。
少し交通整理できたのかな?という感じでした。
実際、あとやれることと言っても、使っていないモジュールをインクルードしないようにするとか、ログファイルの書き出しをいったん止めてみるとか、大したチューニングがないことに気づきました。

PHPはどうなの?

PHPの設定にもMemoryLimitなどの設定がありますから、少し、現実的な数字の範囲でチューニングしてみました。
多少の改善は見られましたが劇的な改善には至りません。
そんな中でガツッと時間が半分になったところがありました。
それは、PHPのプロセス数関係の処理です。
おそらくこれは、PHP-FPMを採用した時に使うことができる設定のようで、要は、PHPの処理を同時に何プロセスまで許容するかを設定する項目です。
こちらが未設定(=無制限。。だと思われる)だってのでとりあえず10と入れてみました。そうしたところ一気に5秒を切る程度までパフォーマンス改善しました。
ここで、思考が行きつきました。もしかして、WEBサーバーの接続プロセスが飽和状態なんじゃ???と。

nginxを今回使わなかった理由

今回、ハイパフォーマンスと言われるnginxを採用しなかったのはここにつきます。
Pleskのトラフィック制限設定はnginx採用時には使うことができないので、今回はnginxを使わずにApacheとしました。
結果、満足の行くパフォーマンスを出せましたので無理にnginxを使うことをやめたということです。

Apache、PHP、DBの設定をほとんどいじらず満足の行くパフォーマンスを実現

前段のPHPのチューニングでパフォーマンスが上がったことをによって、一つの仮説ができました。それは、

同時立ち上げプロセスがCPUの数以上になると、CPUは【CPU/総プロセス】にパフォーマンスが落ちるから、CPUコア数未満の同時プロセス数にしなければいけない。
CPUのロードが1コアに対して1プロセスであれば1秒未満(ほとんどの場合瞬殺)で処理できるが、同時にプロセスが立ち上がれば立ち上がるほどCPUに対して順番待ちが増え(ウェイトプロセスが増える)、結果SynFloodのような状態になる。なので、トラフィック制限設定で同時接続数をCPUコア数以下にすればもしかしたら、各サーバーのチューニングをしなくても、負荷を制御できるのではないか?

と推測しました。
なので、CPUコアを10(リソースを追加する)として、同時接続数を10と20でベンチマークテストをしてみたところ、見事にWEBを表示するまでの時間にちょうど2倍程度の差が生まれました。
これによって、同時プロセスを制御すればある程度負荷のの制御が効くことがわかりました。が。その時点でCPUコアはMAXで20が限界(ALTUSの設定仕様の上限値が20)というのもわかっているので、同時アクセス50という数字から推測すると、2.5~3秒程度かかってしまうのではないかと推測しました。

次に、トラフィック制限もう一つの制限、【帯域幅の制限】です。
この制御については昔からよくどの文献にでも書かれているのですが、『接続数と帯域幅は、両方を設定して初めて良いパフォーマンスを出せるので必ず両方を設定すること』
と、よく注意されています。
実はいまいちわかっていませんでした。

帯域幅制限とは1回の接続で使える通信速度に制限をかけるものです。
これをかけていない場合、マシンスペック、ネットワークカードの持つ上限いっぱいで通信します。仮に接続数が1ならMaxパフォーマンスで早く通信するわけです。
最大速度で通信しているプロセスがあった場合、次のプロセスはその前のプロセスが終了するまで通信せず待機します。
帯域に制限がされていた場合、1つのプロセスで使う帯域は制限されている中で上限値までの範囲で通信を行いますので、余剰帯域幅が生まれ、その余剰帯域を利用して次のプロセスが同時に通信できる余剰が出来上がります。
帯域に制限をかけた場合、余剰があったとしても、制限設定の上限値以上では通信しません。
とはいえ、WEBコンテンツであれば多くても1MB程度の容量ですし、今回は一番重いページでも20MB程度。
有する通信速度を10で割っても2秒以内で表示する程度のファイル容量です。
なので、同時接続数を10、トラフィック制限を1/11程度(少し余裕を見て多めに割った)と設定を行いベンチマークテストを行ってみました。

驚くようなテスト結果

結果。成功しました。
2秒とかからないパフォーマンスを導き出しました。
最後は、帯域制限の同時接続数を1まで落としてテストしてみましたが、1~10程度はCPUのコア数に合わせた方がパフォーマンスがいいことがわかりました。
帯域制限をかけたことで、むしろ交通整理が完全になり、渋滞を起こさずスムーズに通信が流れるようになりました。

まとめ

今回結果としてやったことは3つです

  1. ApacheのKeepAliveをOnにした
  2. 同時接続数をCPUコア数より小さい数字を設定した
  3. 帯域幅制限で有する帯域幅を上記の接続数より大きい数字で割った帯域値を入力

の3つです。
これらは、
KeepAlive設定を行うことで、1度の通信でコンテンツをまとめて落とすように設定をしたうえで、同時セッション数をCPUより小さい数字にすることで、CPUにかかる負荷を100%以下に抑え、帯域幅の制限を行うことで、各セッションの帯域に波ができないようにしたことで、Maxパフォーマンスを生み出しました。
感触としては、CPUが20あった場合、同時接続が1,000くらいでも、ちょっともっさりかな?っていう程度の感じでWEBサイトを表示できます。
同時アクセス1000というのは、1日1000万PV以上のサイトで起きるかもしれない同時アクセスです。(帯域幅はさすがにギガビットクラスを占有していないと捌き切れないかもしれませんが。)

今回はこれにてうまくいきましたのでメモがてら記録に残しておきます。

※追記~実際に授業で使ってみた!~

先般、お客様より実際にこの設定のサーバーで授業をやってみた結果のご報告をいただきました。
当初想定の50人より多く70人程度が接続することになったそうです。
↑こちらについては私たちの方では同時接続100でベンチマークテスつを行っていたので許容範囲でした。
しかしながら、同時に70人がドン!ってアクセスするものではないわけなので、あとで通信ログを確認してみると、実際の同時接続はせいぜい20人程度でした。
サーバー上では1秒違えば同時とは言わないので、同時接続20人×3秒=60セッション程度でした。
なので、何の問題もなかったそうです。
重くなるどころか、通常営業時と何ら変わらず運用できたそうです。
1年後にはテストがあるわけですが、その際には、もう少し同時アクセスになる確率は高くなりそうですが(同じくらいの速度で進行する人が出てきそう)、それでも十分満足の行くパフォーマンスだったそうです。
費用面でも、当初予算を立てていた予算よりずいぶん安く上がりそうだそうで、大満足の結果となりました。

SNSでもご購読できます。