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

Monthly Archives: 4月 2016

You are browsing the site archives by month.

PHP7を同時接続25,000/秒、webを36台ならべて負荷計測してみた

●PHP7を、商用環境で使いたい!

さて、PHP7が2015年12月に正式リリースされてから、早4か月が経ちました。
そろそろ安定してきたかな…、と思いつつも、まだまだ商用環境に導入するのは不安だと思います。

「本当にPHP7って高速なの?」
「PHP7って安定して動くの?」

いろいろな不安があるかと思います。
何しろ、PHP5からのメジャーバージョンアップですから。
普通に考えたら、まだ時期尚早かもしれません。

でも、やはり使いたい。
なにしろ、PHP5と比較して2倍の速度で動作するというのは、大きな魅力です。

そこで、「本当に商用環境で使えるか」という観点で、「リアルな」検証をしてみたいと思います。

●本当に使える、リアルな計測をしよう!

PHP7はPHP5に比べて、高速に動作するという触れ込みです。
実際に「だいぶ速くなったよ」といった検証結果が多く見受けられます。

しかし「これだ!」という検証内容がなかなか見つからないわけです…。

例えば、プログラミングで言うところのハローワールドレベルのものや、単純なコマンドをひたすらループさせたもの等々。
何でもそうですが、ベンチマークで計測した速度と実際に使ってみたときの速度って、結構違いますよね。

とにかくリアルなプログラムで計測したい。
そこで実際に弊社で開発中のアプリケーションを使って負荷試験をしてみました。
しかも、結構な高負荷をかけて。

「安定して動く」プログラムが「安定して動かなくなる」のは、負荷が上がってリソースがひっ迫したときや、並列性が上がったときではないでしょうか。
PHP7自体も勿論プログラムの集合体ですから、問題が発生するとすれば、そういったタイミングと推測できます。

さて、実際に負荷をかけてみました。

●高負荷で計測しよう!

※サーバ構成/ミドルウェアについては、開発中のアプリケーションということでぼかしてあります。お察しください…。

サーバ 台数 CPUコア数 メモリ(GB) 備考
web(APIサーバ) 36 8 16 内訳:34台がPHP5、2台がPHP7。
分散はLVSにより実現(分散方式は単純なラウンドロビン)
DB(master/slave) 3 40 120
KVS(memcached/redis) 3 4 16

 

ミドルウェア バージョン
php 7.0.4
apache 2.2系
MySQL 5.5系
memcached 1.4.16
redis 2系

 

その他
負荷ツールはjmeterを使用
jmeterからのアクセスは外部ネットワーク経由
jmeterを稼働させるクライアントマシンは25台
jmterシナリオは、実際のアプリケーション操作をシミュレートしている
jmeterはrampupやwaitを入れることで実行タイミングをずらしている(実際のユーザーのプレイ状態に近づけるため)
cactiを使用して各種サーバ負荷を計測
newrelicも使ってみました

 

●計測結果

レスポンスタイム

・newrelicによる計測結果です。
・jmeterからのリクエストを、平均して75msec程度で処理しています。内訳は、以下の通りです。

  • MySQLが10msec程度
  • Memcachedが数msec
  • Redisは一瞬
  • PHPは60msec強(但し、 DB処理等のウエイトも含まれる)

・この辺はアプリケーションの作りによるため、PHP5/PHP7の比較とは直接無関係ですが、アプリケーションの性質を理解するための参考値としてご参照ください。
・ちなみに当該グラフはPHP5のwebサーバにて取得しています。

スループット

・スループットです。webサーバ一台に対して、ページビューで約120/sec程度の負荷がかかっているとご理解ください。
・web台数が36台ですので、ページビューの総計は約4,320/secとなります。
・こちらのグラフも負荷の規模を理解するための参考値とお考えください。

※以下は、web02がPHP5のグラフ、web36がPHP7のグラフとなります。

CPU

・CPU負荷です。コアごとにグラフが分割されていますので100%が最大値となります。
・負荷は全CPUに綺麗に分散されている状態です(つまりどのコアも同程度の負荷)
・PHP5は80%程度のCPU使用率ですが、PHP7は40%程度となります。大きな差ですね。

Load Average

 

・ロードアベレージです。グラフの単位が異なっていることにご注意ください。
・PHP5は15~20程度ですが、PHP7は1以下です。
・jmeterからのリクエストはラウンドロビンにより分散していますので単純に比較はできませんが、同じ処理をするのであれば圧倒的にPHP7の方が軽いということは解ると思います。

コンテキストスイッチ

・コンテキストスイッチ(タスク切り替え)の回数です。
・実運用上あまり問題にならない数値ではありますが、PHP5に比べてPHP7の方が多いことが確認できます。
・並列性を高めることで高速化に寄与する仕組みなのかもしれませんが、掘り下げた調査はしていません(すいません)。

メモリ

・メモリ使用量です。
・一番下の茶色い部分が実メモリ使用量です。その上の肌色の層がキャッシュ、緑の層が空き領域です。
・PHP5が12Gbytes使用しているのに比べ、PHP7は8Gbytes程度です。CPU同様、大きな差ですね。
・PHP7の方がキャッシュ使用量が多いのも、良い意味で期待ができるところです。

参考までにDBのクエリ処理状況

・マスターDBが処理したクエリの状況です。内訳は以下となります。

  • 赤色…select
  • 黄色…insert
  • 緑…update
  • ピンク…その他も加えた総数

(他にdeleteなどもあるが見えない程度)
・秒間で20,000クエリ以上捌いているようなアプリケーションを動かしている、というところから色々と想像を膨らませていただければ幸いです。

その他

以下は、PHP5/PHP7で差が無いグラフです(PHP5のものだけ張ってあります)
トラフィック等は変わらなくて当たり前の数値ではありますが、あくまでも参考ということで…

●使っても大丈夫そう、でも…

負荷計測は約6時間続けましたが、特に大きな問題は発生していません。
安定して動作していたと言える結果でした。

性能面では、特にCPU、メモリについて大きな差が見受けられました。
明らかにPHP7の方が性能が良いと言って間違いないと思います。

今回のテストの場合、それぞれのwebサーバが処理しているページビューの数はほぼ同一ですので、全てのwebサーバをPHP5からPHP7に置き換えた場合、webサーバの台数がかなり削減できると推測されます。

ちなみにコードレベルでのPHP5->PHP7への移行コストは一般的に低いと言われているようですし、実際、今回の負荷計測に使用したアプリについては、かなり移行コストが低かったという事実もあります。

しかし問題は、言語仕様の違いよりもインタプリタ(ライブラリ)の違いにあるのではないでしょうか。

例えばインタプリタ(ライブラリ)内部のバグで、apacheがsegmentation faultで落ちたりすると…
いや、素直に落ちてくれればまだ良いのですが、中途半端に生き残ってクライアントからの接続をacceptできたりする状態だと、障害に繋がる可能性が高くなるわけです。
昔であればライブラリ内部をアセンブラレベルでトレースして、「メモリコピーのときにアライメントがずれて落ちてますよ今すぐ何とかしてくださいよこっちは寝てないんですよ」などとライブラリベンダに文句を付けたりしていたわけですが、
現在はそんな時代でもなく、さらに言えば、そんなことをするくらいならPHPなんか最初から使わないわけです。

つまりは、低コストで安全に使えないと意味がないのです。

PHP7が枯れるまでは大き目のバグfixや、セキュリティ問題の修正等によるアップデートが続くと予測されますので、運用コストの一部として十分に考慮する必要があります。
アップデートによるエンバグも怖いですから、いきなり本番環境のPHPをアップデートするわけにもいかないですしね…。

せっかくサーバ費用を削減しても、運用コストが増えてしまったのでは本末転倒です。
なかなか難しいですね…。