August 17, 2003

MovableType を mod_perl (Apache::Registry) 環境下で動かす方法

[ Movable Type ]

最近、「MovableType は Perl で書かれてるから重い」てな発言を時々目にしたりしますが、それが「PHP や Java で書かれたウェブアプリケーションと比べて」という話であった場合には、川合孝典さんの書いた 'PerlよりPHPの方が軽くて速いは本当?' や 'JavaはPerlよりも比較にならないほど速い?' を読んでみろと小一時間問い詰めたくなります。

確かにごくごく標準的な環境下で CGI プログラムとして MovableType (のCGI)を動作させた場合、結構な負荷になると思います。一部のホスティング業者では夜間の負荷制限に引っかかってしまって rebuild に失敗したりするという話も聞いていますし。

しかしそれはあくまで標準的な環境でのお話。mod_perl 環境下で動かすとその体感速度は劇的に向上します。正直、mod_perl じゃない環境へはもう戻れません。PHP や Java で書かれた blog ツールなどと速度比較する場合には、川合さんの文書にもあるように、この環境と比較することも検討して欲しいと思う今日この頃。

というわけで、mod_perl (Apache::Registry) 環境下で MovableType を動作させる方法をちょろっとまとめておきます。実践できる環境は一部に限られてしまいますが、興味のある方は是非お試し下さい。

まずは mod_perl が動作する環境の整備から。Apache と mod_perl をサーバにインストールします。ここでは Apache はバージョン 1.3 系を、mod_perl は 1.X 系を使います。Apache は 2.0 系でもあまり大差ないと思いますが、 mod_perl の 2.0 系は開発版なので、1.X 系が良いでしょう。今回は、

Downloading Apache から apache_1.3.28.tar.gz
mod_perl: Download から mod_perl-1.0-current.tar.gz

をダウンロードしました。

まずは Apache のコンパイルとインストール。mod_perl をインストールする場合、方法は二つあり、ひとつは直接 Apache に静的に組み込む方法、もう一つは Apache DSO を利用して、Apache のコアとは分離させて組み込む方法。ここでは汎用性の高い後者を採用します。そのため Apache をコンパイルする際、DSO サポートを有効にします。

$ tar zxvf apache_1.3.28.tar.gz
$ cd apache_1.3.28
$ CFLAGS=-O2 ./configure \
> --enable-rule=SHARED_CORE \
> --enable-module=all \
> --enable-shared=max
$ make
$ su
Password: 
# make install

これで /usr/local/apache に Apache がインストールされます。パスを他にしたい人は、

$ ./configure --prefix=/usr/local/apachce_test \
(以下同じ)

などとすれば良いでしょう。

次に mod_perl のコンパイルとインストール。USE_APXS=1 オプションを有効にすることで、mod_perl が DSO としてビルドされます。このとき、先にインストールした Apache に含まれる apxs という実行ファイルが必要になります。apxs のパスを WITH_APXS オプションで指定します。その他のオプションにはすべて yes で答えるということで、EVERYTHING=1 オプションも付けます。

# exit
$ cd ..
$ tar zxvf mod_perl-1.0-gurrent.tar.gz
$ cd mod_perl-1.28
$ perl Makefile.PL \
> USE_APXS=1 \
> WITH_APXS=/usr/local/apache/bin/apxs \
> EVERYTHING=1
$ make
$ su
Password: 
# make install

これで完了です。(以降、Apache のインストールディレクトリを $APACHE_HOME とします。)

$APACHE_HOME/libexec の中に、libperl.so というファイルがあると思います。これが DSO でビルドされた mod_perl の本体になります。

試しに Apache を動かしてみましょう。デフォルトの設定では Port 8080 になってるかと思います。試験的に動かすだけなので、そのままで。

# cd $APACHE_HOME/bin
# ./apachectl start
./apachectl start: httpd started

http://(サーバのホスト名またはアドレス):8080/ にアクセスして Apache のデフォルト画面が表示されたら OK です。

次に mod_perl の動作を確認します。mod_perl に標準で付属している Apache::Status モジュールを利用すると、mod_perl に関する様々なステータスやデバッグ情報をブラウザに出力させることができます。試しに Apache::Status を動かしてみて mod_perl の動作確認とします。(『Apache 拡張ガイド』には、CPAN の Devel::Symdump モジュールが必要だとありますが、僕の環境ではそれなしで動きました。万が一動作しない場合は CPAN から Devel::Symdump や Data::Dumper あたりをインストールしてみてください。)

Apache::Status を利用するには $APACHE_HOME/conf/httpd.conf に以下の記述を追加します。追加する場所は、<Directory "..."> といったディレクテブが記述されてる近辺がいいかと思います。(もちろん、<Directory "..."> 〜 </Directory> の中に書いてはいけません。)

<Location /perl-status>
  SetHandler perl-script
  PerlHandler Apache::Status
</Location>

Apache を再起動して設定を読み込ませます。

# cd $APACHE_HOME/bin
# ./apachectl graceful
./apachectl graceful: httpd gracefully restarted

http://(サーバのホスト名またはアドレス):8080/perl-status/ にアクセスして Apache::Status の出力が得られれば OK です。ちなみに、この Apache::Status の "Loaded Modules" メニューでは、そのとき mod_perl が読み出しているモジュールの一覧を見ることができますが、MovableType を mod_perl で動かした際には MT モジュール関連が読み出されていることが確認できますので、動作確認に使えます。(それ以外にも "Inheritance Tree" ではクラスの継承マップがツリー表示されるので、MovableType のコード解析にも役立ったりします。)

さて、次は MovableType のインストール。ここは割愛します。/path/to/mt にインストールしたこととします。MovableType の動作確認しようと思ったけど CGI が動かねーよ!! ってな方は Google で "AddHandler cgi-script ExecCGI" とか検索すれば良いかと思います。

あと、docs、images、style.css は mt.cgi は別のディレクトリに切り分けた方が無難かもしれません。(see '困った時には')

さて、いよいよ mod_perl で MovableType の実行を高速化します。

(以下、うんちく。読み飛ばしていただいて結構)

そもそも mod_perl を使うと何で速くなるのかという話ですが、簡単に言うと、Perlインタプリタをサーバに組み込むことによって Perl コードから Apache API に直接アクセスすることを可能とし、Perl の起動によるオーバーヘッドやCGI実行時の子プロセス生成のオーバーヘッドをカットすることで 200% 〜 2000% の高速化が可能となる、という仕組みです。

通常、CGI プログラムはその実行が完了すると、そこで役目を終えてその動作を終了しますが、mod_perl で動作する Perl コードは初回の実行時にメモリ上にキャッシュされ、以降のアクセスはそのメモリに常駐したプログラムが処理することになります。単に Perl 起動時のオーバーヘッドなどが回避されるだけでなく、メモリに常駐することでデータベースへの接続を永続化(コネクションプーリング)したりすることも可能になります。

(うんちく終わり)

mod_perl を使って CGI プログラムを動かすには、(mod_perl に標準で含まれる) Apache::Registry や Apache::PerlRun といったモジュールを使って CGI 環境エミュレートを行い、その下で動作させます。これらのモジュールは先に説明した Perl コードのメモリ常駐化などを一手に担ってくれます。ただし、Perl スクリプトに含まれるグローバル変数などの取り扱いに注意が必要になり、Apache::PerlRun よりも Apache::Registry の方がその辺りの制限に対して厳くなっています。その分、Apache::Registry の方がより高速です。MovableType のコードは Apache::Registry によって動作させることが可能になっています。

MovableType を Apache::Registry 環境下で動かすためには mod_perl には含まれない Apache::Request と Apache::Cookie のインストールが必要になります。(これらのモジュールは libapreq 配布に含まれています。) CPAN 経由でインストールできます。

# perl -MCPAN -e shell
cpan> install Apache::Request

僕がインストールしたときは、make test で失敗しましたが、無理やりインストールしました。force install Apache::Request とするなり、~/.cpan/build に展開されたディレクトリで make install するなりで OK だと思います。(ほんとにそれでいいのかしら。)

次に、$APACHE_HOME/conf/httpd.conf に以下を追加します。(/path/to/mt は MovableType をインストールしたディレクトリに適時読み替えてください。)

PerlSetEnv PERL5LIB /path/to/mt/lib:/path/to/mt/extlib
PerlModule Apache::Registry
<Directory "/path/to/mt">
  SetHandler perl-script
  PerlHandler Apache::Registry
#  PerlModule Apache::DBI
  Options +ExecCGI
  PerlSendHeader Off
</Directory>

MovableType のマニュアルには PerlSetEnv の行は含まれていないのですが、僕の環境ではこれが無いと動きませんでした。データベースに MySQL や PostgreSQL などを使っている場合は、PerlModule Apache::DBI のところをコメントアウトするとコネクションプーリングが有効になり、更に幸せになれます。(なれるはず。ほんとにちゃんとできてるか調べてない。)

書き加えたら Apache を再起動して、mt.cgi にアクセスしてみてください。

# cd $APACHE_HOME/bin
# apachectl graceful
./apachectl graceful: httpd gracefully restarted

mod_perl の性質上、初回起動時はそんなに速くないかもしれませんが、二度目以降のアクセスは劇的に速くなっているかと思います。

長くなったし以上、と言いたいところですが、コードを一箇所だけ修正する必要があります。BookMarklet を使おうとすると "Undefined subroutine &CGI::unescape called at /usr/local/apache/htdocs/app/mt/lib/MT/App/CMS.pm line 639. " とか言われてしまうので、/path/to/mt/lib/MT/App/CMS.pm で use Jcode; とかしているところで

use Jcode;
use CGI;
use Symbol;
...

と use CGI の一文を加えてください。

以上、mod_perl 環境下で動作させるための方法をざーっと書きましたが、ウェブサーバーの細かい設定なんかは全く書いてないので、公開する場合はその辺怠り無く。

ちなみに(まだちなむのか)、MovableType のマニュアルには更に高速化させる方法として mod_perl ハンドラとして動作させる方法も載ってます。

Posted by naoya at August 17, 2003 02:28 AM | トラックバック (28)  b_entry.gif
トラックバック [28件]
TrackBack URL: http://mt.bloghackers.net/mt/suck-tbspams.cgi/356
movabletype BerkeleyDBからMySQLへ移行
Excerpt: 最近エントリーの数が増えてきたせいか、rebuildの速度が気になってきました。そこで前々から興味があったのが mod_perl化。しかし、NDO::Weblogの中のひらたさんのコメントで MovableType を mod_perl (Apache::Registry) 環境下で動かす方法 Rebuild 自体は Berkeley DB...
Weblog: のまのしわざ
Tracked: September 17, 2003 04:00 PM
movabletype BerkeleyDBからMySQLへ移行
Excerpt: 最近エントリーの数が増えてきたせいか、rebuildの速度が気になってきました。そこで前々から興味があったのが mod_perl化。しかし、NDO::Weblogの中のひらたさんのコメントで MovableType を mod_perl (Apache::Registry) 環境下で動かす方法 Rebuild 自体は Berkeley DB...
Weblog: のまのしわざ
Tracked: September 17, 2003 04:45 PM
mod_perlで高速化
Excerpt: MovableTypeが遅い(なぜならServerはPower Mac G3 B&H 350MHz)!!と感じたので、高速化を決意。いろいろ調べてみたら、mod_perl用に動かすと結構高速化できるらしいことを発見。うちのApache先生はmod_perl & mod_ruby & mod_sslでコンパイルしてある(DSOではなくbuild-in...
Weblog: Fenrir's BLog
Tracked: September 30, 2003 03:15 PM
mod_perl
Excerpt: 200MHzのCPUだと遅くてイヤになってたけどなんとかがんばって mod_perlにしたらまだちょっと遅いけどまあ問題にならないぐらいの スピードになった。 NDO::Weblog: MovableType を mod_perl (Apache::Registry) 環境下で動かす方法 はじめ画像が出なかったんだけど、 <Lo...
Weblog: MustangType
Tracked: November 15, 2003 07:09 PM
日本語化パッチ更新しました
Excerpt: 日本語化パッチを更新しました。(ダウンロードはこちら) NDO::Weblogのnaoyaさんに指摘を受けた箇所を主に修正しました。 1. lib/MT/XMLRPCServer.pm を書き換えるようにした。 EUC版のみ修正です。naoyaさんのパッチをそのまま適用させていただきました。これで、moblo...
Weblog: Milano::Monolog
Tracked: November 23, 2003 01:49 PM
このサイトの MT を mod_perl 化しました。
Excerpt: perl を 5.6.2 にアップグレードしたのと同時に(5.8.x は FreeBSD 4系では make で Segmentation Fault してしまいインストールできないのだ。。)、Movable Type も mod_perl で動くように設定してみました。 mod_perl ハンドラ化もできるようですがとりあえず Apache::Re...
Weblog: blog.bulknews.net
Tracked: November 26, 2003 02:58 PM
mod_perl化
Excerpt: 今更ながらにこのサイトのMovableType を mod_perl化してみました. NDO::Weblog: MovableType を mod_perl (Apache::Registry) 環境下で動かす方法 がとても参考になりました.感謝感謝です. ウチのサーバはFreeBSDなので必要な Perl Module は全部 ports でインストー...
Weblog: hogeLog
Tracked: November 27, 2003 01:46 AM
MTのmod_perl化
Excerpt: ふと思いついて、MTをmod_perlで動かそうと思い、ググる。 NDO::Weblog:さんのMovableType を mod_perl (Apache::Registry) 環境下で動かす方法を参考にあっという間に設定は終わった。 NDO::Weblog:さんと全く同じでApache::Requestのmake testにコケるし、PerlSetEnvも...
Weblog: Blogle Development::Deblog
Tracked: December 24, 2003 11:36 AM
コメント/FrontPage
Excerpt: FrontPage 「砂かけババア」で水木しげるさんを提訴~~スプーンおばさんネタでつか -- 2002-12-25 (水) 13:45:56 電撃らぐな (*´ー`*) -- 2003-01-15 (水) 10:55:42 最低映画館〜さよならジュピター セキュリティ情報 -- 2003-01-16 (木) 15:54:01 ノートPCでリネージ...
Weblog: PukiWiki/TrackBack 0.1
Tracked: January 3, 2004 09:54 PM
サーバーのmod_perl化、でもCGI実行禁止にすると…
Excerpt: 一部の方から「mod_perl化するといいよ」と言われていたので、ついに1月2日、サーバーの設定を少しいじって、このMovable Typeをmod_perl化しました。 mod_perl化については、MT本家のページ(その翻訳版)やnaoyaさんの解説により、すんなり移行できて「よかったよかった...
Weblog: Sync A World You Want To Explore
Tracked: January 4, 2004 11:13 AM
mod_perlで高速化
Excerpt: MovableTypeが遅いので、mod_perlによる高速化を試みました。 参考にしたのは、NDO::Weblogさんとfenrirさんの記事で(ありがとうございます)、合わせ技で以下のように設定しました。 まず、mod_perlとをports(www/mod_perlとwww/p5-libwww)でインストールし、httpd.confの...
Weblog: らぢゅん's Blog
Tracked: January 16, 2004 10:26 AM
mod_perlで高速化
Excerpt: MovableTypeが遅いので、mod_perlによる高速化を試みました。 参考にしたのは、NDO::Weblogさんとfenrirさんの記事で(ありがとうございます)、合わせ技で以下のように設定しました。 まず、mod_perlとをports(www/mod_perlとwww/p5-libwww)でインストールし、httpd.confの...
Weblog: らぢゅん's Blog
Tracked: January 16, 2004 10:30 AM
MTをmod_perlで動かす
Excerpt: コメントSPAM対策をほどこしたので、たまってるゴミコメントを削除したが、自分のMTはCGIで動いているうえに、マシンはP133、メモリ200M程度なので、このままではやる気がおきないので、MTをmod_perl環境で動かすようにしようと重い腰を上げた。 mod_perl自体はSledgeを動...
Weblog: blog::hiroron.com
Tracked: April 7, 2004 03:57 PM
mod_perl化
Excerpt: 今回、サーバを変更するついでにNDO::Weblog: MovableType を mod_perl (Apache::Registry) 環境下で動かす方法を参考に高速化しました。...
Weblog: Tony Tony Chopper Weblog
Tracked: April 11, 2004 10:24 PM
Apache1.3+mod_perl
Excerpt: あまりにMovableTypeの動作が遅いのでどうにか早くしようと頑張ってみた。 MovableType を mod_perl (Apache::Registry) 環境下で動かす方法 mod_perlを使えば早くできるらしい。 ってなわけで、今動いてるApacheが2.0だったのでそのままmod_perlを導入してみた… ダメだ...
Weblog: 日暮日記 参
Tracked: April 23, 2004 12:50 AM
ページ再構築
Excerpt: 昨日、シャワーを浴びて寝るかというタイミングでネットしてたら、「MovableTypeが重い」っていう記事がいろいろ出てきて、確かにウチのも重たいなぁって興味深く読んでました。記事数が80件近くなった頃から、新規で投稿しようとすると、サーバのハードディスクが「カ...
Weblog: COLOR NO.A
Tracked: June 1, 2004 10:54 AM
ページ再構築
Excerpt: 昨日、シャワーを浴びて寝るかというタイミングでネットしてたら、「MovableTypeが重い」っていう記事がいろいろ出てきて、確かにウチのも重たいなぁって興味深く読んでました。記事数が80件近くなった頃から、新規で投稿しようとすると、サーバのハードディスクが「カ...
Weblog: COLOR NO.A
Tracked: June 1, 2004 10:57 AM
サーバーのmod_perl化、でもCGI実行禁止にすると…
Excerpt: 一部の方から「mod_perl化するといいよ」と言われていたので、ついに1月2日、サーバーの設定を少しいじって、このMovable Typeをmod_perl化...
Weblog: Sync A World You Want To Explore
Tracked: July 14, 2004 11:48 PM
mod_perl導入
Excerpt: 休日表示カレンダープラグイン導入の際に Date::Japanese::Holiday モジュールを入れられたのに気をよくして、mod_perlも入れてみました...
Weblog: buslog
Tracked: August 1, 2004 01:57 AM
mod_perl化
Excerpt: Movable Type 3.01D-jaの動きがもっさりしているので、mod_...
Weblog: kkobaのblog
Tracked: August 22, 2004 12:06 PM
mod_perl化
Excerpt: 多くの先人の皆様のおかげで、無事mod_perl化できました。ありがとうございました。私の環境は玄箱+Debian3.0(Woody)です。
Weblog: uep on hayate
Tracked: November 17, 2004 05:05 PM
Movable Type 3.121-ja の mod_perl 環境でエラー
Excerpt: MovableType を mod_perl (Apache::Registry) 環境下で動かす方法を参考にさせてもらって、ようやく mod_perl 環境下...
Weblog: mega green oasis +
Tracked: December 15, 2004 12:13 AM
mod_perl導入
Excerpt: MovableTypeをカスタマイズするたびに再構築が必要であるが、 この作業が...
Weblog: Kblog
Tracked: December 21, 2004 02:42 PM
mod_perl
Excerpt: MT+mod_perl
Weblog: PukiWiki/TrackBack 0.1
Tracked: January 27, 2005 12:35 AM
mod_perl 実装完了
Excerpt: 最近、エントリーの数が多くなり、BLOG 再構築時に必ずといっていいほど「Con...
Weblog: ものづくり日記
Tracked: March 7, 2005 05:18 PM
mod_perlのインストール
Excerpt: どうもブログの更新で 遅いのが気になったので ...
Weblog: The-Photograph.net
Tracked: March 31, 2005 01:08 AM
libapreq2系でのmod_perl。
Excerpt: Apacheが2系。 mod_perlも伴い2系。(正確には1.99-) そうな...
Weblog: 実践サーバー構築記
Tracked: May 5, 2005 01:27 AM
mod_perl と movabletype
Excerpt: mt.cgi を使うには、mod_perl 等の環境がないと遅すぎてつらい。 m...
Weblog: blog.wore.ma.cx
Tracked: September 4, 2005 11:13 PM
コメント [5件]

遅れ馳せながら、わたしもやってみました。管理画面のきりかわりがサクサクしていいですね。わたしは、おとなしく(?) mt のマニュアル通りにやりました。普段、apache2 を使っているので、1.3 も立ち上げたりしましたが。メモリもCPUもプアなうちのマシンでは負荷が大きいような気がするので、今後も使うか考え中...。

Apache::Request のインストールでテストがうごかないのは、コンパイル時に apache のヘッダファイルの include に失敗いるからでは? うちではpathを直してインストールしました。(libapreq)/c/apache_request.h の #include "httpd.h" から始まるブロックです。

Rebuild 自体は Berkeley DB を使っていると、あんまり早くならないような気がしました。mysql にして、DB を別マシンに移すと早くなった気がします。150エントリーで、40秒かかっていたものが、30秒になった、ってところです。このへんは、Perl とかよりも、もう三年も頑張っているうちの非力なマシンとディスクの問題のような気がします。

ちなみに、TrackBack の use CGI; って追加しなくても動くような気がするんですが、どういうときに起きる問題だったんでしょうか? あと、PerlSetEnv は最初の <Perl> のところで指定しているので、それで書かれていないのだとおもいます。

[1] Posted by: hirata at September 13, 2003 09:33 AM [返信]

どうもです。

libapreq の make test のエラーは、その後調べたところ、Apache の apxs が原因でした。僕の環境では RPM から入れた Apache とソースから作った Apache が混在していて、mod_perl を後者に合わせて作ったにも関わらず前者に付属する apxs を読みにいってしまって、テストできねーよってエラーでした。

環境変数 PATH に後者の Apache の bin のパスを入れて解決しました。

use CGI の件は、みらのさんの日本語化パッチを当てた場合に Bookmarklet で CGI::unescape が使われていて、そいつを取り込めずに undefined subroutine になってましたので、use CGI を加えてます。

今のパッチでは直ってるかもしれません。

[2] Posted by: naoya at September 13, 2003 06:59 PM [返信]

> Bookmarklet で CGI::unescape

意味わかんないですね。w

Bookmarklet のコードのところで CGI::unescape、が正しいか。

[3] Posted by: naoya at September 13, 2003 07:00 PM [返信]

参考にさせていただいてます。

Apache::Statusを設定してみるところで、Locationタグが閉じてなくてエラーになってます。

ご報告まで。

[4] Posted by: み。@びぎねっと at January 8, 2004 01:29 AM [返信]

>>4 み。さん

あ、すいません、誤記です。直しました!

ありがとうございます。

[5] Posted by: naoya at January 8, 2004 12:29 PM [返信]