2011年10月03日

チューニンガソン2で2位でした

はてなブックマークに登録

10/1(土)にチューニンガソン2 というイベントに参加してきました。 もちろん前回に引き続き優勝を 目指していたのですが、今回は残念ながら2位でした。 今回もどんなチューニングをしていたのかの記録を公開します。
(ちなみに優勝したのは元KLabの濱野さんで、同じく メモを公開されています。)

今回のチューニンガソンのお題は、 Wikipedia の高速化で、 MediaWiki と Wikipedia の データが入った MySQL のデータには修正を加えずに、ランダムな100ページの表示速度を競いました。 マシンはメモリ1GBでデュアルコアのものが2台で、今回はWebサーバーの部分は自由に構成できます。

1. ボトルネックの確認

とりあえず AMI Linux の標準の php + apc で計測したところ、1ページの表示に1秒くらい使っています。 またphpか!ということで、やっぱりCPUがボトルネックです。topを見ながら負荷をかけたところ、 前回よりはMySQLの負荷も若干高いですが、やっぱりphpのCPU使用率が一番の負荷でした。

閑話休題. phpはなぜ遅い?

phpはなぜ遅いのかというと、1回のWebリクエストを捌く度に全てをリセットするからです。

10年前のCGI全盛時代はまだWebアプリは小さくて、毎回プロセスを生成しないphpは高速だと言われていました。 しかしO/RマッパーやMVCフレームワークが一般的に使われるようになってどんどんWebアプリが 肥大化することで、Webアプリの起動速度(フレームワークやO/Rマッパーが定義する大量のクラスや 関数をインタプリタにロードしたり、設定ファイルを読み込んだり、etc...)が重くなり、 phpもどんどん遅くなっていきます。

一方、Perl,Python,Ruby などではWebリクエストのたびにアプリ自体を再起動しない方式が一般的になり、 リクエストのたびにまっさらな状態に戻るphpは現代では一番遅いWeb用言語になってしまっています。 APCやeAcceleratorは、phpのソースコードのコンパイル結果をキャッシュすることで phpを倍くらい速くしますが、それでもまだまだ起動速度がボトルネックなのは変わりません。

2. GREE Fast Processor の導入

前回と同じチューニングだけでは勝てそうにないので、phpの最大のボトルネックである 起動コストをショートカットできる GREE Fast Processor を導入することにしました。GREEさんのBlogによれば2倍から7倍の 高速化が期待できます。 (逆に言えば、実行時間のうち1/2〜6/7が起動時間ということですね)

php を大幅に高速化するには他にも Mongrel2 (phpのドライバが FastCGI や mod_php のように全体を再起動しないので GREE Fast Processor と同じ効果が見込める) や Facebook の Hiphop PHP (phpコードをC++にトランスレートしてしまう)がありますが、 mongrel2 は触ったことがないのと、Hiphopはビルドが一日作業で動くようになるまでに競技が 終わってしまうので見送りました。

ただ、導入と言っても一筋縄ではいかず、Blog記事やコードを見ながらアプリを対応させて、 実際に動かそうとしたら AMI Linux の php には posix 系関数が無いために動かず、 php-5.4beta を持ってきたら今度は GREE Fast Processor のビルドが通らず、、、という感じで 試合時間の半分以上過ぎたところでやっともう少しで動かせそうなところまで持って行きました。

ここで、重大な事実が判明します。Webサーバーは自由に変えられますが、DocumentRootの 変更とアプリのコードの変更は不可でした。コードをいじらないでGREE Fast Processor を動かすのはほぼ不可能です。 遅刻してルールをきちんと聞いていなかった僕の自業自得です。

3. php-5.4のビルド

慌てて方針転換して、仕事で経験がある 前回と同じphp自体のチューニングで勝負することにします。 前回と同じMySQLやApacheのチューニングはもちろんしたうえで、前回よりもAPCの設定を詰めます。 そして、前回忘れていたのですが、 php の実行エンジンのビルドオプションも変更しておきます。 以前このBlogでphpを高速化する computed goto という記事を書いたのですが、命令ディスパッチにかかるコストが減って数%の高速化が期待できます。

4. nginxでリバースプロクシ

今回はサーバーが2台使えるので、nginxを使って2台のサーバーにリクエストを分散させる事に しました。ただし、計測時にクライアントから2つのWebサーバーにリクエストをしてもらうことも できたうえに、計測時の並列数が4でコア数と同じなので、リバースプロクシすることにより CPUが空いているサーバーにリクエストをとばす効果は期待できません。単に自分でやってみたかっただけです。

5. 計測

今回は計測前に一旦サーバーを再起動するというルールだったのですが、計測前に短い時間だけ 操作することができたので、APCキャッシュが空の状態のまま計測されることを避けるために 動作確認も兼ねてブラウザで数回アクセスして置きました。

その後結果発表があったのですが、最初に書いたとおり2位でした。優勝した濱野さんは 最初のほうでファイルキャッシュを使う選択をしてそれが見事にヒットした一方、 僕はミスで最初に取った戦略を放棄することになったのが最大の敗因だと思います。

最後に

前回に比べて時間が増え、サーバーが2台になったことで、工夫する余地がぐっと増えたので 疲れたけれどとても楽しかったです。「前回優勝者」というプレッシャーもなくなったことですし、 次回参加できれば前回・今回とはもっと違った方向のチューニングを試してみたいです。


@methane
klab_gijutsu2 at 23:05│Comments(0)TrackBack(0)

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント