coding, photo, plant and demo

*mod_pagespeedを試してみるも挫折

tech btz 20101106 010645
mod_pagespeedなるapache2のresponseの最適化を勝手に行うmodが出たようだ。

htmlやjsの無駄な構文を削ってくれたり、cssやjs、画像のhtmlへの埋め込みを自動で行うとのこと。
なんと、このサイトで自力で頑張ってある程度実装していたものを勝手にやってくれるのか!
流石google様!憎いぜ!

mod_pagespeed
http://code.google.com/intl/ja/speed/page-speed/docs/using_mod.html

早速試している人もいた。
mod_pagespeed をちょっとだけ試してみた - 酒日記 はてな支店
http://d.hatena.ne.jp/sfujiwara/20101104/1288841616

僕も試してみたいが、先ずはmod_pagespeed無しでどの程度動くのか調べてみよう。

fastcgiを無効にしたこのサイトを試してみる。
$ ab -n 1000 -c 100 localhost/non-fastcgi

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        Apache/2.2.8
Server Hostname:        localhost
Server Port:            80

Document Path:          non-fastcgi
Document Length:        39839 bytes

Concurrency Level:      100
Time taken for tests:   99.768793 seconds
Complete requests:      1000
Failed requests:        2
   (Connect: 0, Length: 2, Exceptions: 0)
Write errors:           0
Total transferred:      40061246 bytes
HTML transferred:       39759322 bytes
Requests per second:    10.02 [#/sec] (mean)
Time per request:       9976.879 [ms] (mean)
Time per request:       99.769 [ms] (mean, across all concurrent requests)
Transfer rate:          392.13 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    7  24.3      0      84
Processing:   833 9688 9797.0   6851   66301
Waiting:      829 9588 9635.3   6813   66300
Total:        917 9696 9796.4   6852   66384

Percentage of the requests served within a certain time (ms)
  50%   6852
  66%   7661
  75%   8207
  80%   8780
  90%  18619
  95%  35984
  98%  44538
  99%  54660
 100%  66384 (longest request)
10req/s。何このショボイ数値。

では実際ここで運用しているfastcgi有りの場合。
Server Software:        Apache/2.2.8
Server Hostname:        localhost
Server Port:            80

Document Path:          /blog/
Document Length:        39839 bytes

Concurrency Level:      100
Time taken for tests:   3.222161 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      40130000 bytes
HTML transferred:       39839000 bytes
Requests per second:    310.35 [#/sec] (mean)
Time per request:       322.216 [ms] (mean)
Time per request:       3.222 [ms] (mean, across all concurrent requests)
Transfer rate:          12162.33 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.2      0       4
Processing:     4  291 279.4    261    3060
Waiting:        3  290 279.4    261    3060
Total:          6  291 279.4    261    3063

Percentage of the requests served within a certain time (ms)
  50%    261
  66%    268
  75%    276
  80%    281
  90%    627
  95%    704
  98%    769
  99%   1599
 100%   3063 (longest request)
310req/sか。31倍になってるけどこの程度か、という感じ。
cache拾って投げてるだけなのに。

試しに同じコンテンツをfileとして置いてみた。
Server Software:        Apache/2.2.8
Server Hostname:        localhost
Server Port:            80

Document Path:          /~mtm/tmp/cachedindex.html
Document Length:        39839 bytes

Concurrency Level:      100
Time taken for tests:   0.152034 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      40271382 bytes
HTML transferred:       39918678 bytes
Requests per second:    6577.48 [#/sec] (mean)
Time per request:       15.203 [ms] (mean)
Time per request:       0.152 [ms] (mean, across all concurrent requests)
Transfer rate:          258672.40 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0       2
Processing:     2   13   2.7     14      28
Waiting:        1   12   2.7     13      28
Total:          4   13   2.4     14      28

Percentage of the requests served within a certain time (ms)
  50%     14
  66%     15
  75%     15
  80%     15
  90%     16
  95%     16
  98%     17
  99%     17
 100%     28 (longest request)
6577req/s、圧倒的に速いですね。
これが理論値とすればまだまだ改善の余地ありなわけだ。
memcached辞めて素直にruby上でcacheしようかな。分散するわけでもないんだから。
またはcache関係だけFastCGI+Cで書き直すか!
てかmod書くか、いやそれくらいなら自分でhttpd書くか!ってそんな元気ない。


では次にpagespeedを有効にする。
標準の/etc/apache2/mods-available/pagespeed.confはModPagespeedUrlPrefixだけ変更してgo。

まずはfastcgi有り。
Benchmarking cygx-9 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests

Test aborted after 10 failures

apr_socket_connect(): Cannot assign requested address (99)
Total of 365 requests completed
なんと完走してくれない。
それ以前に端末が激重くなり反応しない。
なんとか頑張ってapache2のrestartを成功させて一命を取り留める。
そのときのtopを取ると大量のapache2とindex.fcgiが湧いていて、如何にもやばい雰囲気。

non-fastcgiも一応試したが、同じ結果。


どうなってんだこりゃ?
調べてみると同じ症状になる人はいるらしい。

Had to uninstall as too many httpd's processes were being forked
http://groups.google.com/group/mod-pagespeed-discuss/browse_thread/thread/58c8b1e2e2433470?pli=1

Q:通常20個のhttpdが225個まで増えて途方もなく重くなるんだが。エラーログはこんな風だ。
A:ModPageSpeedFileCachePathのパスにhttpdの書き込み権限を与えてくれ。
Q:errorは無くなったが、プロセスはやっぱり増えまくるんだが。
A:そりゃそうだ。HTMLを最適化して書き直したり、画像を圧縮したりするから最初は大変なんだよ!

なるほど。
単純に初回のキャッシングが重いということらしい。
そういえばこのサイトは画像を貼り付けまくってある。
さらにlogを見るとお行儀の悪いHTMLのせいでパースに苦労しているようだ。自業自得か。
何れにせよ僕の場合はfree lunchは無かったということだ。

こういった不毛な最適化を勝手にサーバでやってくれるのは正しいと思うので、最初の負荷の制御さえうまくいけば、すぐにでも使いたいんだけどね…

あと今更だけどひとつ重要なことに気付いた。
mod_pagespeedはページ全体の転送量やリクエストを減らす仕組みなのだから、
単体のhtmlに対するGETを繰り返すapachebenchでは有効な性能評価は出来ない。
むしろjsやcssや画像の埋め込みが行われたら、benchの結果は悪くなってしまうはずだ。
(キャッシュの性能は分かりますが)

ということでまとめると、
  • サイトによっては初期のキャッシュ構築の負荷が異常に高く、サーバがしばらく無反応になる恐れがあるので注意
  • apachebenchではなくブラウザでInspector等を使って計測しないと真価は分からない

結局のところ、なんの役にも立たないチラ裏ですね、この記事。