ひさしぶりにapacheの設定とか

apache2のMPM(multi processing module)について少々。

http://httpd.apache.org/docs/2.2/mpm.html

worker threadはスケーラビリティ、preforkは安定性・互換性って書いてある。若い世代の僕にとっては、java=thread、c=fork、って覚えるのが簡単。

preforkのほうは読んで字のごとく、接続が来る前にあらかじめforkしておいて、待ち受けポートへの接続がきたらそのforkされた子プロセスに通信を引き継ぐかんじ。手元のgentooさんがお釈迦ったので確認できないけど、おそらくconfigure時に指定しなければLinuxではpreforkが標準で選ばれると思われる。

安定性・互換性を求めるならprefork、っていうのは、つまり、

プロセス間にて意図しないリソースの共有(javaでいうクラス変数)を発生させなくて済む

ってことじゃないかしら。ほら、同一リクエストの中では複数回の同一クラス参照で同じ値を読み書きしたい、ってことがあるでしょ、多分。でもそれってちゃんと実装してないと別リクエストに影響及ぼす(及ぼされる)わけですから。
スレッドセーフなモジュール以外を使わないようにするか、あるいはこのような問題があると分かってworker使う以外はprefork使ったほうがハマらなくて無難なんでしょうね。
ドキュメントによると、以下のポイントは抑えておいたほうがよさげ。

  • MaxClientsのデフォ値は256*1
  • MaxClients個以上のアクセスは受け付けない。が、ListenBackLog個までキューイングする。ListenBackLogはDoS攻撃、多分synflood系の対策時に設定変更したりする値だったと記憶。
  • ふやしすぎるとスラッシングの問題があるかも(swap in/outの繰り返しによるI/Oオーバヘッドの過多、それに伴う性能低下)
  • パフォチューについてはここを見たまえだそうだ。

workerは一つの子プロセスに複数スレッド走らせることで処理効率を上げる、そんなところでしょうか。forkにせよインスタンス生成にせよ、重複するようなデータ分のメモリを確保し展開するには容量食うし時間も食うから。変更される予定のない値は一度メモリ上に読み込まれたらあとはシェアすればいいじゃん、ってことなのかしら。


今日はこの辺で寝る。

*1:要出自