Apacheの高速化: eacceleratorとmod_perl
Webで動的なページを作るとき、私は通常ページはPHP、CGIにはPerlを使っています。これらの処理が遅いと思ったことは特にないのですが、各々を高速化するソフトウェアがあります。私が書いているコードは大した行数ではないので効果は薄いかもしれませんが、PHPで書かれているserendipityには多少なりとも効果があるかもしれないと思い、導入してみることにしました。
PHPの高速化eacceleratorの設定
eacceleratorというものがあるのを最近知りました。Apacheには元々PHPのインタープリターが組込まれているので、特に高速化手段はいらないものと思っていましたが誤解であったようです。仕組としては、コンパイル済みコードをメモリ/ハードディスクにキャッシュしておくようです。(PHPも実行時コンパイルする仕掛だったのですね)
ソースはEacceleratorのプロジェクトページから取得することができます。
cd eaccelerator-0.9.5.2/
export PHP_PREFIX="/usr"
/usr/bin/phpize
./configure --prefix=/usr --sysconfdir=/etc --infodir=/usr/share/info --mandir=/usr/share/man \
--enable-eaccelerator --enable-shared --enable-static
make
しかし、何故かphpizeでエラーします。以下のように"/usr/bin/phpize"を修正します。色々インストールしていたからでしょうか。phpizeを修正してから、再度実行します。
6,7c6
< #phpdir="`eval echo /usr/lib`/build"
< phpdir="/usr/lib/php4/build"
---
> phpdir="`eval echo /usr/lib`/build
make install
ls -la /usr/lib/php4/
mkdir /var/cache/eaccelerator
chown apache.apache /var/cache/eaccelerator
chmod 700 /var/cache/eaccelerator
cp eaccelerator.ini /etc/php.d/
cp control.php /var/www/html/usage/ #-- 適宜場所を変えて下さい
/etc/rc.d/init.d/httpd restart
httpdのrestartの前には、"/etc/php.d/eaccelerator.ini"を編集しておきましょう。
eaccelerator.cache_dir = "/var/cache/eaccelerator"
eaccelerator.allowed_admin_path = "/var/www/html/usage/" #-- 上記設置場所に
動作状況は、http://yourhost/usage/control.phpをアクセスすると表示されます。(この画面から設定もできるようです)
Perl CGIの高速化: mod_perl
通常PerlはCGIとして動かされています。つまり、別プロセスとして起動したperlによって処理されています。
mod_perlはこのインタプリタをapache組み込みにするものです。従って、プロセス起動のオーバーヘッドを短縮することができます。
mod_perlは各ディストリビューションで配布されていますので、インストールして下さい。
perlスクリプトは、通常のCGIとは共存できないようですので、cgi-binのディレクトリとは別に用意します。(例 /var/www/perl)。
このとき、/etc/httpd/conf.d/perl.conf に以下を追加します。
Alias /perl /var/www/perl
<Directory /var/www/perl>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
PerlOptions +ParseHeaders
Options +ExecCGI
</Directory>
これで設定は完了です。httpdを立ち上げ直せば動作します。以下の"hello.cgi"を置くとmod_perlのバージョンが表示されます。
#!/usr/bin/perl -w
print "Content-type: text/html\n\n";
$s = <<EOL;
<html><head><title>Hello CGI, mod_perl</title></head><body>
Hello, CGI !!<br/>
MOD_PERL=$ENV{'MOD_PERL'}
</body></html>
EOL
print "$s\n";
しかしながら、cgi-binから/var/www/perlにCGIを移動しただけでは、簡単には動作しないようです。
まず、ライブラリのサーチパスが変わってしまい、カレントディレクトリは含まれません。これに対しては、
"use lib '/var/www/perl'; "
を頭に挿入して対処しました。
しかしながら、CGIの中で使っているライブラリの中でエラーしてしまうため、動きませんでした。(環境のせいでしょうか)
効果や考察など
さて、効果ですが、計測していません。eacceleratorのほうは動いていて、遅くなることはなさそうですのでそのまま使っています。特にエラーも出ていないようです。
mod_perlのほうはちゃんとは動いていないので、使うことができていません。くやしいので少し考察してみました。
ラフな見積もりとして、空のプロセスを立ち上げて実行時間を計ってみます。
localhost$ time for i in `seq 1 1000`; do ./bar; done
real 0m0.629s
user 0m0.160s
sys 0m0.450s
localhost$ time for i in `seq 1 1000`; do true; done
real 0m0.012s
user 0m0.010s
sys 0m0.000s
ここで、"bar"はmain(){exit(0);}だけのプロセスです。trueはbashの組み込みコマンドなので、プロセス起動コストの大まかな評価としてはこれで良いでしょう。
これで見ると、プロセス1個の起動に掛かる時間は大体600μ秒くらいでしょうか。とりあえずは、問題のないオーバーヘッドと思われます。アクセスが極度に多いサーバ、かつ、一回のCGIで行っている処理が軽い場合には無視できないかもしれません。