Apache httpサーバが2.2系から2.4系にアップデートされた事がキッカケでした。せっかくなので、USEフラグを攻めてみようと。そしたらば…MPMという指定がOFFになっていたのです。ヽ(~~~ )ノ ハテ?MPMってなんだろう?
Multi Processing Moduleという名称からも分かるように、mpmとはapacheの並列処理を行うmoduleです。
ほほう、なるほど…並列処理用のモジュールの指定、ということだったのね。せっかくアップデートするのであれば、ピカピカの状態で使用したい、と言うことで、Apache+PHPの実行環境を攻めて行くこととします。
ApacheのMPMにはいくつか種類があり、必ず実行プロセスについて1つだけを指定します。同時利用はNGです。さて、どんな種類があるか?
一般的に使用されるのはprefork/worker。eventは2.2系ではExperimental(実験的)サポート、2.4系では標準推奨のMPMです。ちなみに、preforkよりもworkerの方が動作効率は良いです。何故ならば…プロセスの起動/停止/切り替えはOSにとって重い処理、スレッドの起動/停止/切り替えは軽い処理だからです。よし!それじゃあworkerかeventで決まり!と言いたいところですが、そうはなかなか行きません。スレッドは、メモリ空間を共有するため、きちんと排他処理されていないと誤動作する可能性が高いのです。きちんと処理されている処理系のことを、スレッドセーフな実装と言います。スレッドセーフじゃない処理系を使用する場合は使用するべきではありません。
/etc/portage/make.confに、以下の記載を追加します。ちなみに、今回は攻めるので、event MPMで高速なWebサーバを目指します。
APACHE2_MPMS=event
# emerge apache2
/etc/apache2/modules.d/00_mpm.confにMPMの動作パラメータが記載されています。これをいろいろいじってやればOK。
だ、そうです。さて、うちではどうして言うかというと-。
StartServers 4 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestWorkers 150 MaxConnectionsPerChild 10000
起動時、StartServers、MinSpareThreadsで待機していますが、同時接続数が増えていくと、ThreadsPerChild数を超えると、MaxRequestWorkersに到達するまで子プロセスを増やします。が、子プロセスのゾンビ化やメモリリークを防ぐために、MaxConnectionsPerChildで上限を決めているのですね。
ポイントは、MaxRequestWorkersで、同時接続の最大数。同時アクセスの最大数はココでサチるということですね。
PHPをマルチスレッドで動作させるのは非推奨だと、PHPホームページに記載されています[8]。やるならFastCGIを使えとのこと。なわけで、FastCGIの設定をしてみます。
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に、余裕を作っておきます。
さらに、start_servers数だけ、最初に起動しておきます。全部埋まらないように、min_spare_serversで、最低限1つ、空きプロセスとして、次のリクエストに備えます。max_spare_serverで、待機しているPHPは4つまでにしておくので、使い終わったらプロセスを終了させます。
というわけで、忙しいときには増え、使い終わるとプロセスを減らすという、賢い動きをしてくれるわけですね♪
PHP5.5移行、PHPに組み込まれています。opcacheはコードキャッシュで、PHPのプログラムを中間コード化してメモリにキャッシュしておきます。そのため、一度実行されたコードを再度コンパイルしないため、応答速度が改善されます。
/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
PECL-APCuは、データキャッシュで、データの読み込みを高速化してくれます。
# 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
これで、php-fpmを再起動してあげます。どうですかね?かなり体感早くなったんじゃありませんか~??
さて、DBのチューニングってのも、課題になりますよね。そこで、こんな便利ツールがあるそうで。
# emerge mysqltuner
さて、mysqltunerをインストールしましたら、実行してみます。DBの管理ユーザ&パスワード聞かれますので、答えます。うちでは、こんな表示が出てきましたよ。
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 (> )
さて、このmysqltuner、サーバの運用実績から、改善事項を提示してきますので、mysqlを起動してから、24時間以上経ってから出したほうが良いみたいです。運用しながら、何回か実施してみて下さい。
テーブルがフラグメントされてるから、最適化しろ、だそうです。こんなコマンドでできます。
# mysqlcheck -u <管理者ユーザ> -p<パスワード> --all-databases --optimize
ちなみに、InnoDBの場合は、最適化ができないので、ALTER TABLEで代用してくれるそうです。ありがたいことだ♪
指示に従って、/etc/mysql/my.cnfを変更してあげます。何回かmysqltunerを実行した結果、あれ直せ、これ直せと指示が出ましたので、以下を調整しました。
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
調整が済んだら、mysqlを再起動しましょう。
# /etc/init.d/mysql restart
join_buffer_sizeを大きくしろ、と散々言われます。が、そもそも、インデックス作る方が高速化につながるそうなので、join_bufferをいくら増やしても、アプリ側を変更しないと追いつかない、ということで、増やさなくてもOKというネット記事がありましたので、うちではココまでにしております。
正直、爆速になりました。以前は、正直Wehページが描画される様が目で見て解るぐらいちんたらしていて、まぁ、Webアプリだからこんなもんかな、と半ば諦めていたのですが、2回め以降のページ表示が人間の体感で一瞬で終わります。人の目で見てあきらかに違うので、かなり効果があったと言えるでしょう。超快適♪
(This host) = https://femt.ddo.jp