4: 2013-03-08 (金) 16:34:25 maruo[6] [7] | 現: 2018-02-21 (水) 22:48:21 maruo[6] [8] | ||
---|---|---|---|
Line 1: | Line 1: | ||
*ふとしたキッカケ [#we75a40b] | *ふとしたキッカケ [#we75a40b] | ||
- | Apache httpサーバが2.2系から2.4系にアップデートされた((2013/3/6現在、GentooのStableは2.2系に戻ってますが…))事がキッカケでした。せっかくなので、USEフラグを攻めてみようと。そしたらば…MPMという指定がOFFになっていたのです。ヽ(~~~ )ノ ハテ?MPMってなんだろう? | + | Apache httpサーバが2.2系から2.4系にアップデートされた事がキッカケでした。せっかくなので、USEフラグを攻めてみようと。そしたらば…MPMという指定がOFFになっていたのです。ヽ(~~~ )ノ ハテ?MPMってなんだろう? |
Multi Processing Moduleという名称からも分かるように、mpmとはapacheの並列処理を行うmoduleです。 | Multi Processing Moduleという名称からも分かるように、mpmとはapacheの並列処理を行うmoduleです。 | ||
ほほう、なるほど…並列処理用のモジュールの指定、ということだったのね。せっかくアップデートするのであれば、ピカピカの状態で使用したい、と言うことで、Apache+PHPの実行環境を攻めて行くこととします。 | ほほう、なるほど…並列処理用のモジュールの指定、ということだったのね。せっかくアップデートするのであれば、ピカピカの状態で使用したい、と言うことで、Apache+PHPの実行環境を攻めて行くこととします。 | ||
+ | |||
+ | *設計指針 [#i522c57d] | ||
+ | -入力が捌けなくて落ちない様に、奥(PHPやMySQL)は広く、入り口(Apache)を狭く設定しておく | ||
+ | -プロセス/スレッド/キャッシュ数は、なるべく理にかなった方法で | ||
*Apache MPMの設定 [#ob0e20a5] | *Apache MPMの設定 [#ob0e20a5] | ||
Line 17: | Line 21: | ||
**MPMを選択してコンパイルする [#v968b11e] | **MPMを選択してコンパイルする [#v968b11e] | ||
- | /etc/portage/make.confに、以下の記載を追加します | + | /etc/portage/make.confに、以下の記載を追加します。ちなみに、今回は攻めるので、event MPMで高速なWebサーバを目指します。 |
- | APACHE2_MPMS=prefork/worker/itk/perchild/event(どれか一つを選ぶ) | + | APACHE2_MPMS=event |
- | ちなみに省略すると問答無用でworker MPMが選択されます。で、いつもの | + | |
# emerge apache2 | # emerge apache2 | ||
**MPMのチューニング [#g3659aef] | **MPMのチューニング [#g3659aef] | ||
- | /etc/apache2/modules.d/00_mpm.confにMPMの動作パラメータが記載されています。これをいろいろいじってやればOK。今うちでは2.2系を運用しているので、worker MPMを動かしています | + | /etc/apache2/modules.d/00_mpm.confにMPMの動作パラメータが記載されています。これをいろいろいじってやればOK。 |
:StartServers|最初に起動する子プロセスの数 | :StartServers|最初に起動する子プロセスの数 | ||
:MinSpareThreads|最小の待機スレッド数 | :MinSpareThreads|最小の待機スレッド数 | ||
:MaxSpareThreads|最大の待機スレッド数 | :MaxSpareThreads|最大の待機スレッド数 | ||
:ThreadsPerChild|子プロセスの中のスレッド数 | :ThreadsPerChild|子プロセスの中のスレッド数 | ||
- | :MaxClients|最大同時接続待機数 | + | :MaxRequestWorkers|最大同時接続ワーカー数 |
+ | :MaxConnectionsPerChild |子プロセスの最大数 | ||
- | だ、そうです。どれぐらいにするかは悩みどころですが…いろいろいじくってみたところ、なんだか不安定になってしまったので、デフォルト設定のまま使ってます。 | + | だ、そうです。さて、うちではどうして言うかというと-。 |
- | ちなみに、4コアでevent MPMをチューニングして、静的コンテンツのリクエスト送受信で最速だったのはこんな設定だって。Apache 2.4系でないと使えないディレクティブ混じってます。 | + | |
StartServers 4 | StartServers 4 | ||
- | MinSpareThreads 4 | + | MinSpareThreads 25 |
- | MaxSpareThreads 4 | + | MaxSpareThreads 75 |
- | ThreadsPerChild 2 | + | ThreadsPerChild 25 |
- | MaxRequestWorkers 2 | + | MaxRequestWorkers 150 |
- | MaxConnectionsPerChild 0 | + | MaxConnectionsPerChild 10000 |
- | 出展は[[このページ>http://blog.matsumoto-r.jp/?p=2996]]です。 | ||
- | が、これを参考にやってみたところ、なんかしばらくするとリクエスト受け付けなくなるんだよねぇ…多分、静的コンテンツの最適値で、PHPとか使用した動的コンテンツの場合は、1ページ表示する際にHTTPリクエストが多発するので、要求が受け切れなくなっちゃうんだろうね…LAMP((Linux/Apache/MySQL/PHP))の典型的Webサーバは、デフォルト値のまま運用するほうがいいみたいですね~。 | + | 起動時、StartServers、MinSpareThreadsで待機していますが、同時接続数が増えていくと、ThreadsPerChild数を超えると、MaxRequestWorkersに到達するまで子プロセスを増やします。が、子プロセスのゾンビ化やメモリリークを防ぐために、MaxConnectionsPerChildで上限を決めているのですね。 |
- | **PHPの並列動作について [#x23dbc12] | + | ポイントは、MaxRequestWorkersで、同時接続の最大数。同時アクセスの最大数はココでサチるということですね。 |
- | PHPをマルチスレッドで動作させるのは非推奨だと、[[PHPホームページに記載されています>http://www.php.net/manual/ja/faq.installation.php#faq.installation.apache2]]。やるならFastCGIを使えとのこと。マルチスレッドなMPM(workerやevent)を使用する場合、2つの選択肢があります。 | + | |
- | +スレッドセーフなPHPを使って、mod_phpから動かす(Zend Thread Safety対応のPHPを使う) | + | |
- | +FastCGIで動かす | + | |
- | さてー、うちではどうしたか?FastCGI設定してみたのですが、致命的な不具合があって、断念しました。XoopsのWordPressモジュールが表示されませんでした。Apacheが | + | *PHPの並列動作について [#x23dbc12] |
- | Premature end of script headers: index.php, | + | PHPをマルチスレッドで動作させるのは非推奨だと、[[PHPホームページに記載されています>http://www.php.net/manual/ja/faq.installation.php#faq.installation.apache2]]。やるならFastCGIを使えとのこと。なわけで、FastCGIの設定をしてみます。 |
- | こんなメッセージ吐いちゃって… index.phpがCGIとしてまともに動かないとかなんとか。(;´д`)トホホ。なので、mod_php+スレッドセーフなPHPで、いいやと。 | + | |
- | さて、それぞれ見てみましょう | + | **FastCGIをやってみる [#ba4fc5cb] |
- | ***スレッドセーフなPHPか? [#e995976b] | + | さて、FastCGIの設定は、[[このページ:http://femt.ddo.jp/modules/xpwiki/?Gentoo%20Linux%E3%81%AA%E7%94%9F%E6%B4%BB%2F%E8%A4%87%E6%95%B0%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AEPHP%E5%90%8C%E6%99%82%E8%B5%B7%E5%8B%95%E3%81%A7%E6%82%A9%E3%82%80]]のApache&PHP7.1の部分だけ設定すると、うまくいきますよ~ |
- | 確かめる方法があります。 | + | |
- | <?php | + | |
- | phpinfo(); | + | **チューニング [#za32aded] |
+ | pm = dynamic #下記パラメータに従って動作する | ||
+ | pm.max_children = 100 #最大同時接続数 | ||
+ | pm.start_servers = 4 #最初に起動しておくプロセス数 | ||
+ | pm.min_spare_servers = 1 #待機させておくサーバの最小数 | ||
+ | pm.max_spare_servers = 4 #待機させておくサーバの最大数 | ||
- | ?> | + | さて。pm.max.childrenまで子プロセスを増やします。このプロセス数が、接続数の上限です。先程、Apacheの同時接続数を150にしておきましたので、うちでは2バージョンのPHPを起動しておきますので、2つで最大200まで。Apacheの奥にいるPHPに、余裕を作っておきます。 |
- | こんな内容のphpファイル(phpinfo.phpとします)を作って、Webサーバからアクセスできるところにおきます。http://example.com/phpinfo.php等。すると、PHPの設定がずらずらと出てきます。以下の2つに注目 | + | |
- | :Debug Build|noであること | + | さらに、start_servers数だけ、最初に起動しておきます。全部埋まらないように、min_spare_serversで、最低限1つ、空きプロセスとして、次のリクエストに備えます。max_spare_serverで、待機しているPHPは4つまでにしておくので、使い終わったらプロセスを終了させます。 |
- | :Thread Safety|enabledであること | + | |
- | 上記が満たされていれば、スレッドセーフなPHPです。mod_phpから使用しても問題ないでしょう。ちなみに、GentooのパッケージでコンパイルされるPHPはスレッドセーフなPHPでした。PHPをコンパイルする際に、--enable-maintainer-ztsをつけてコンパイルすればスレッドセーフなPHPが出来るはずです。 | + | というわけで、忙しいときには増え、使い終わるとプロセスを減らすという、賢い動きをしてくれるわけですね♪ |
- | ***FastCGIをやってみる [#ba4fc5cb] | + | **PHPのキャッシュ(opcacheとPECL-APCu)を設定する [#j4b51446] |
- | CGIとは何か。CGIとは、Webサーバからスクリプトを呼び出す仕掛けです。例えばperl/ruby/python/bash... PHPも場合によってはありえます。が、普通にCGIを使用すると、 | + | ***opcache [#u827a9a1] |
- | +WebサーバのプロセスからFork | + | PHP5.5移行、PHPに組み込まれています。opcacheはコードキャッシュで、PHPのプログラムを中間コード化してメモリにキャッシュしておきます。そのため、一度実行されたコードを再度コンパイルしないため、応答速度が改善されます。 |
- | +perl等のプロセスを起動 | + | |
- | +スクリプト実行 | + | |
- | +プロセスを終了する | + | |
- | と、とても重い処理になってしまいます。FastCGIとは、予めperl等、スクリプトを実行したいプロセスを起動させておき、スクリプトイメージだけを起動済みプロセスに渡し、処理してもらった結果を受け取ってHTTPで返すことで、プロセスの起動/終了に関わるオーバーヘッドを軽減する仕組みです。 | + | /etc/php/XXX-phpX.X/php.iniの以下の項を設定します。 |
+ | opcache.enable=1 | ||
+ | opcache.enable_cli=1 | ||
+ | opcache.memory_consumption=128 | ||
+ | opcache.interned_strings_buffer=8 | ||
+ | opcache.max_accelerated_files=10000 | ||
+ | opcache.revalidate_freq=1 | ||
+ | opcache.save_comments=1 | ||
- | ちなみに、mod_phpとFastCGI、どちらが高速か?と言うと…少ないリクエストではmod_php、大量のリクエストを処理するならばFastCGIに軍配が上がるそうです。FastCGIの方がスケーラビリティが高いという言い方をしますね。 | + | **PECL-APCu [#o94d9b71] |
+ | PECL-APCuは、データキャッシュで、データの読み込みを高速化してくれます。 | ||
+ | ***コンパイル [#ob16f023] | ||
+ | # emerge dev-php/pecl-apcu | ||
+ | さて、インストールされたAPCuを設定いたします。/etc/php/XXX-phpX.X/extの下にある、apcu.iniに、以下の項を追加。 | ||
+ | apc.shm_size=128M | ||
+ | apc.ttl=86400 | ||
+ | apc.gc_ttl=86400 | ||
- | とりあえず、設定の仕方だけ記載しておきますね。[[参考は、このページです>http://mattmcadoo.com/content/mini-howto-setting-php-fpm-apache-gentoo]] | + | これで、php-fpmを再起動してあげます。どうですかね?かなり体感早くなったんじゃありませんか~?? |
- | まず、phpのuseフラグにfpmを追加し、 | + | *MySQLのチューニング [#i44d3b73] |
+ | さて、DBのチューニングってのも、課題になりますよね。そこで、こんな便利ツールがあるそうで。 | ||
- | # emerge --newuse -vuD world | + | **mysqltuner [#y25ba22d] |
+ | # emerge mysqltuner | ||
- | 次に、MASKされているwww-apache/mod_fastcgi_handlerをインストールします。/etc/portage/package.keywordsにwww-apache/mod_fastcgi_handlerを追加して | + | さて、mysqltunerをインストールしましたら、実行してみます。DBの管理ユーザ&パスワード聞かれますので、答えます。うちでは、こんな表示が出てきましたよ。 |
- | # emerge www-apache/mod_fastcgi_handler | + | General recommendations: |
+ | Run OPTIMIZE TABLE to defragment tables for better performance | ||
+ | Reduce or eliminate persistent connections to reduce connection usage | ||
+ | Upgrade MySQL to version 4+ to utilize query caching | ||
+ | Adjust your join queries to always utilize indexes | ||
+ | Set thread_cache_size to 4 as a starting value | ||
+ | Increase table_cache gradually to avoid file descriptor limits | ||
+ | Variables to adjust: | ||
+ | max_connections (> 151) | ||
+ | wait_timeout (< 28800) | ||
+ | interactive_timeout (< 28800) | ||
+ | join_buffer_size (> 64.0M, or always use indexes with joins) | ||
+ | thread_cache_size (start at 4) | ||
+ | table_cache (> ) | ||
- | そして、 /etc/apache2/modules.d/70_mod_php5.confを編集します。 | + | さて、このmysqltuner、サーバの運用実績から、改善事項を提示してきますので、mysqlを起動してから、24時間以上経ってから出したほうが良いみたいです。運用しながら、何回か実施してみて下さい。 |
- | # Load the module first | + | |
- | LoadModule php5_module modules/libphp5.so | + | ***OPTIMIZE TABLE [#yb23c069] |
+ | テーブルがフラグメントされてるから、最適化しろ、だそうです。こんなコマンドでできます。 | ||
+ | # mysqlcheck -u <管理者ユーザ> -p<パスワード> --all-databases --optimize | ||
- | # Set it to handle the files | + | ちなみに、InnoDBの場合は、最適化ができないので、ALTER TABLEで代用してくれるそうです。ありがたいことだ♪ |
- | #AddHandler application/x-httpd-php .php .php5 .phtml | + | ***my.cnfの調整 [#la2a6cac] |
- | #AddHandler application/x-httpd-php-source .phps | + | 指示に従って、/etc/mysql/my.cnfを変更してあげます。何回かmysqltunerを実行した結果、あれ直せ、これ直せと指示が出ましたので、以下を調整しました。 |
- | AddHandler fcgi:/var/run/php-fpm.socket .php .php5 | + | join_buffer_size =1M |
+ | table_open_cache = 8192 | ||
+ | max_connections = 150 | ||
+ | wait_timeout = 20000 | ||
+ | interactive_timeout = 20000 | ||
+ | thread_cache_size = 4 | ||
+ | query_cache_type = 1 | ||
+ | query_cache_limit = 16M | ||
+ | query_cache_size = 512M | ||
+ | skip-name-resolve = 1 | ||
+ | innodb_buffer_pool_instances = 7 | ||
- | DirectoryIndex index.php index.phtml | + | 調整が済んだら、mysqlを再起動しましょう。 |
+ | # /etc/init.d/mysql restart | ||
- | 続いて…/etc/php/fpm-php5.3/php-fpm.confをいじります | + | join_buffer_sizeを大きくしろ、と散々言われます。が、そもそも、インデックス作る方が高速化につながるそうなので、join_bufferをいくら増やしても、アプリ側を変更しないと追いつかない、ということで、増やさなくてもOKというネット記事がありましたので、うちではココまでにしております。 |
- | ;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ページが表示されるはずでーす。 | + | |
- | + | ||
- | *PECL-APCでPHPを高速化する [#j8f37c8d] | + | |
- | PHPは、スクリプト言語なので、テキストファイルを読み込んで、実行時にコンパイルして実行しています。このコンパイル時間が処理のオーバーヘッドとなります。PECL-APCとは、一度読み込んでコンパイルしたPHPスクリプトをキャッシングしておき、再度読み込んだ際にキャッシュにヒットすれば、コンパイル済みPHPスクリプトを実行するため、目に見えてページ表示が高速化されます。さて、設定してみましょう。 | + | |
- | + | ||
- | **コンパイル [#i2a76c1b] | + | |
- | うちでは、オプションにmmapを追加してみてます。/etc/portage/package.useに | + | |
- | dev-php/pecl-apc mmap | + | |
- | を追加し、ビルド。 | + | |
- | # emerge dev-php/pecl-apc | + | |
- | + | ||
- | **設定 [#ra1a69a0] | + | |
- | /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用ですね。 | + | |
- | + | ||
- | **動作を見てみる [#o5a7a10b] | + | |
- | /usr/share/php/apc/apc.phpがありますので、これをWebサーバから見える場所に置いて、ブラウザからアクセスしてみましょう。http://example.com/apc.php等ね。 | + | |
- | グラフで、共有メモリの使用状況が見えると思います。ちなみに、うちだと軽く128Mなんて使ってそうな勢いですね~…キャッシュヒット率も97%位いってるので、かなり効果が高いということが分かりますです。 | + | *結果 [#id87c281] |
+ | 正直、爆速になりました。以前は、正直Wehページが描画される様が目で見て解るぐらいちんたらしていて、まぁ、Webアプリだからこんなもんかな、と半ば諦めていたのですが、2回め以降のページ表示が人間の体感で一瞬で終わります。人の目で見てあきらかに違うので、かなり効果があったと言えるでしょう。超快適♪ |
(This host) = https://femt.ddo.jp