mod_perl 2.0 on worker MPM の特性

だらだらと3日にわたって書いてきましたが,明日から遅めのお盆休みになるのでまとめをメモ書きしておきます。

  • worker MPM での mod_perlPerl の ithread を使っている
  • httpd のスレッドプールとは独立して Perl インタプリタプールが存在する
  • Perl インタプリタプールの最大インタプリタ数などは設定で変更可能
    • デフォルトで最大 5(少ない!)
  • インタプリタプールはインタプリタのステート保持構造体のプールであり,インタプリタスレッドのプールではない(実行時アタッチ)←ちょっと推測
    • だから httpd のスレッドプールのスレッド数より多くも少なくも設定できる
    • インタプリタ数が足りなくなったときは空きがでるまでブロックする
  • Perl ithread では変数は TLS (スレッド間で独立したロケーション)に保持され,基本的にスレッドセーフ
  • インタプリタスレッドと協調作業(変数の共有,ロック,セマフォ等)を行いたい場合は,thread::shared モジュールを使えば可能
    • であるが,変数の共有をするためには「親インタプリタ」で変数が定義されていないといけない
    • 具体的にはスタートアップスクリプトで use しておかねばならない
    • とめんどくさいので IPC::ShareLite 等を使った方がよいかも(でも SYSV IPC ってスレッドセーフなのかな?)
  • インタプリタを子インタプリタにクローンする際,データ領域(シンボルテーブル含む)はコピー(not Copy on Write)され,コンパイルドコードは共有される
    • スタートアップスクリプトで読み込むモジュールでデータ領域をたくさん使っている場合はクローンに時間がかかる
    • その代わりコード部分が共有されるのでメモリ消費量はおそれるほどでもない

だから

  • 基本的に threads を明示的に使っているモジュールでない限り,変数領域はスレッド間で独立
  • よって prefork MPM で動いていた mod_perl ウェブアプリ(およびそこから使う CPAN モジュール)は worker MPM でも素直に動く,はず
  • ただし,シグナルハンドラ等については要注意(Perl 5.8 以降で結構良くなってるみたいですが)
    • そんなもの使ってないよと思っていても CPAN モジュールで使っていることもある。例外処理系やデバッグ情報系ナド
    • 実テスト,負荷テストあるのみ!

私感では worker のメリットがあまりよくわかりません(とりたてて軽くないような)。単純なハンドラで apache-bench とると(on Linux),prefork だと Connect が速くて Processing がちょい遅め,worker だと Connect がちょいラグありで Processing が速め,トータルでとんとん,といった感じでした。メモリ消費量ではちょっとお得になるのかなぁ。