ふとしたキッカケ anchor.png

Apache httpサーバが2.2系から2.4系にアップデートされた*1事がキッカケでした。せっかくなので、USEフラグを攻めてみようと。そしたらば…MPMという指定がOFFになっていたのです。ヽ(~~~ )ノ ハテ?MPMってなんだろう?

Multi Processing Moduleという名称からも分かるように、mpmとはapacheの並列処理を行うmoduleです。

ほほう、なるほど…並列処理用のモジュールの指定、ということだったのね。せっかくアップデートするのであれば、ピカピカの状態で使用したい、と言うことで、Apache+PHPの実行環境を攻めて行くこととします。

Page Top

Apache MPMの設定 anchor.png

Page Top

MPMの種類 anchor.png

ApacheのMPMにはいくつか種類があり、必ず実行プロセスについて1つだけを指定します。同時利用はNGです。さて、どんな種類があるか?

prefork
HTTPリクエストに1つのプロセスを割り当てる。つまり、たくさんのリクエストを同時に捌きたい場合には、たくさんプロセスをたちあげておく
worker
HTTPリクエストに1つのスレッドを割り当てる。起動しておくプロセス数、プロセス内のスレッド数は設定によって変更する
itk
preforkと一緒だが、スクリプトを実行するユーザ権限を分けることができる。例えばApacheさんとか、rootさんとか、各ユーザさんとか
perchild
workerと同じ考え方だが、バーチャルホスト毎にプロセス数/実行ユーザを割り当てる
event
workerと同じく、プロセス/スレッドの組み合わせだが、非同期I/O型*2となっており、設定如何では最も高速

一般的に使用されるのはprefork/worker。eventは2.2系ではExperimental(実験的)サポート、2.4系では標準推奨のMPMです。ちなみに、preforkよりもworkerの方が動作効率は良いです。何故ならば…プロセスの起動/停止/切り替えはOSにとって重い処理、スレッドの起動/停止/切り替えは軽い処理だからです。よし!それじゃあworkerかeventで決まり!と言いたいところですが、そうはなかなか行きません。スレッドは、メモリ空間を共有するため、きちんと排他処理されていないと誤動作する可能性が高いのです。きちんと処理されている処理系のことを、スレッドセーフな実装と言います。スレッドセーフじゃない処理系を使用する場合は使用するべきではありません。

Page Top

MPMを選択してコンパイルする anchor.png

/etc/portage/make.confに、以下の記載を追加します

APACHE2_MPMS=prefork/worker/itk/perchild/event(どれか一つを選ぶ)

ちなみに省略すると問答無用でworker MPMが選択されます。で、いつもの

# emerge apache2
Page Top

MPMのチューニング anchor.png

/etc/apache2/modules.d/00_mpm.confにMPMの動作パラメータが記載されています。これをいろいろいじってやればOK。今うちでは2.2系を運用しているので、worker MPMを動かしています

StartServers
最初に起動する子プロセスの数
MinSpareThreads
最小の待機スレッド数
MaxSpareThreads
最大の待機スレッド数
ThreadsPerChild
子プロセスの中のスレッド数
MaxClients
最大同時接続待機数

だ、そうです。どれぐらいにするかは悩みどころですが…いろいろいじくってみたところ、なんだか不安定になってしまったので、デフォルト設定のまま使ってます。 ちなみに、4コアでevent MPMをチューニングして、静的コンテンツのリクエスト送受信で最速だったのはこんな設定だって。Apache 2.4系でないと使えないディレクティブ混じってます。

StartServers 4
MinSpareThreads 4
MaxSpareThreads 4
ThreadsPerChild 2
MaxRequestWorkers 2
MaxConnectionsPerChild 0

出展はこのページです。

が、これを参考にやってみたところ、なんかしばらくするとリクエスト受け付けなくなるんだよねぇ…多分、静的コンテンツの最適値で、PHPとか使用した動的コンテンツの場合は、1ページ表示する際にHTTPリクエストが多発するので、要求が受け切れなくなっちゃうんだろうね…LAMP*3の典型的Webサーバは、デフォルト値のまま運用するほうがいいみたいですね~。

Page Top

PHPの並列動作について anchor.png

PHPをマルチスレッドで動作させるのは非推奨だと、PHPホームページに記載されています。やるならFastCGIを使えとのこと。マルチスレッドなMPM(workerやevent)を使用する場合、2つの選択肢があります。

  1. スレッドセーフなPHPを使って、mod_phpから動かす(Zend Thread Safety対応のPHPを使う)
  2. FastCGIで動かす

さてー、うちではどうしたか?FastCGI設定してみたのですが、致命的な不具合があって、断念しました。XoopsのWordPressモジュールが表示されませんでした。Apacheが

Premature end of script headers: index.php,

こんなメッセージ吐いちゃって… index.phpがCGIとしてまともに動かないとかなんとか。(;´д`)トホホ。なので、mod_php+スレッドセーフなPHPで、いいやと。

さて、それぞれ見てみましょう

Page Top

スレッドセーフなPHPか? anchor.png

確かめる方法があります。

<?php

phpinfo();

?>

こんな内容のphpファイル(phpinfo.phpとします)を作って、Webサーバからアクセスできるところにおきます。http://example.com/phpinfo.php等。すると、PHPの設定がずらずらと出てきます。以下の2つに注目

Debug Build
noであること
Thread Safety
enabledであること

上記が満たされていれば、スレッドセーフなPHPです。mod_phpから使用しても問題ないでしょう。ちなみに、GentooのパッケージでコンパイルされるPHPはスレッドセーフなPHPでした。PHPをコンパイルする際に、--enable-maintainer-ztsをつけてコンパイルすればスレッドセーフなPHPが出来るはずです。

Page Top

FastCGIをやってみる anchor.png

CGIとは何か。CGIとは、Webサーバからスクリプトを呼び出す仕掛けです。例えばperl/ruby/python/bash... PHPも場合によってはありえます。が、普通にCGIを使用すると、

  1. WebサーバのプロセスからFork
  2. perl等のプロセスを起動
  3. スクリプト実行
  4. プロセスを終了する

と、とても重い処理になってしまいます。FastCGIとは、予めperl等、スクリプトを実行したいプロセスを起動させておき、スクリプトイメージだけを起動済みプロセスに渡し、処理してもらった結果を受け取ってHTTPで返すことで、プロセスの起動/終了に関わるオーバーヘッドを軽減する仕組みです。

ちなみに、mod_phpとFastCGI、どちらが高速か?と言うと…少ないリクエストではmod_php、大量のリクエストを処理するならばFastCGIに軍配が上がるそうです。FastCGIの方がスケーラビリティが高いという言い方をしますね。

とりあえず、設定の仕方だけ記載しておきますね。参考は、このページです

まず、phpのuseフラグにfpmを追加し、

# emerge --newuse -vuD world

次に、MASKされているwww-apache/mod_fastcgi_handlerをインストールします。/etc/portage/package.keywordsにwww-apache/mod_fastcgi_handlerを追加して

# emerge www-apache/mod_fastcgi_handler

そして、 /etc/apache2/modules.d/70_mod_php5.confを編集します。

# Load the module first

LoadModule php5_module modules/libphp5.so

# Set it to handle the files

#AddHandler application/x-httpd-php .php .php5 .phtml
#AddHandler application/x-httpd-php-source .phps
AddHandler fcgi:/var/run/php-fpm.socket .php .php5

DirectoryIndex index.php index.phtml

続いて…/etc/php/fpm-php5.3/php-fpm.confをいじります

;listen = 127.0.0.1:9000
listen = /var/run/php-fpm.socket
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
user = apache
group = apache

さらに、/etc/conf.d/apache2をいじります。

APACHE2_OPTS="-D PHP5 -D FASTCGI_HANDLER"

ーD FASTCGI_HANDLER追加ね。

で、apacheとphp-fpmを起動

# /etc/init.d/apache2 restart
# /etc/init.d/php-fpm restart

で、FastCGIがうまく動けばWebページが表示されるはずでーす。

Page Top

PECL-APCでPHPを高速化する anchor.png

PHPは、スクリプト言語なので、テキストファイルを読み込んで、実行時にコンパイルして実行しています。このコンパイル時間が処理のオーバーヘッドとなります。PECL-APCとは、一度読み込んでコンパイルしたPHPスクリプトをキャッシングしておき、再度読み込んだ際にキャッシュにヒットすれば、コンパイル済みPHPスクリプトを実行するため、目に見えてページ表示が高速化されます。さて、設定してみましょう。

Page Top

コンパイル anchor.png

うちでは、オプションにmmapを追加してみてます。/etc/portage/package.useに

dev-php/pecl-apc mmap

を追加し、ビルド。

# emerge dev-php/pecl-apc
Page Top

設定 anchor.png

/etc/php/XXX-php5.3/extの中にapc.iniというファイルが入っているのがわかるかと思います。これを設定してあげればOK。私は

apc.shm_size=128M

を追加しております。PHP用の共有キャッシュメモリに128Mbyteをリザーブする、ということです。apache2-php5.3の下はmod_phpで動くPHP用、cli-php5.3の下はCLIコマンドでのPHP用、fpm-php5.3の下はFastCGIで動くPHP用ですね。

Page Top

動作を見てみる anchor.png

/usr/share/php/apc/apc.phpがありますので、これをWebサーバから見える場所に置いて、ブラウザからアクセスしてみましょう。http://example.com/apc.php等ね。

グラフで、共有メモリの使用状況が見えると思います。ちなみに、うちだと軽く128Mなんて使ってそうな勢いですね~…キャッシュヒット率も97%位いってるので、かなり効果が高いということが分かりますです。


*1 2013/3/6現在、GentooのStableは2.2系に戻ってますが…
*2 リクエスト受信と応答送信を別のスレッドで処理する方式
*3 Linux/Apache/MySQL/PHP

トップ   凍結 差分 バックアップ 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
Counter: 5156, today: 3, yesterday: 4
初版日時: 2013-03-07 (木) 00:38:48
最終更新: 2013-03-08 (金) 16:34:25 (JST) (1595d) by maruo
ページ内検索

ログイン

ユーザー名:


パスワード:





パスワード紛失

メインメニュー

サブメニュー
自宅鯖計画

Gentoo Linuxな生活

玄箱HGにGentoo格闘記

航空ショーへ行こう

モータースポーツな世界

奥深き写真の世界への誘い

我思う ゆえに我あり



携帯用QRコード