これはAdventure Advent Calendar 2018の12日目の記事です。(後追い)
株式会社アドベンチャーに所属してます。
航空券予約サイトskyticket(スカイチケット)を運営してますので、どうぞよろしくお願いします。
今月、PHP7.3がリリースされました。
パフォーマンスがさらに向上したようで、ますますPHP愛が深まります!
そんなPHPに夢中な私ですが、前職ではインフラっぽいことも少しやってました。
今回の記事は、そんな4年前の昔話になりますが、恥ずかしながら『40万PV/1時間』を捌いた際のApache設定を晒すことにします。
チューニング内容はサイト次第で正解が違ってきますが、こんなチューニングでもなんとかなったよー、って感じの参考程度になれば幸いです。
Apacheのこと、まだ見捨てないでー!
今回はApacheの話になります。
Webサーバー市場のシェア率が30%を越え、勢いの止まらない人気のnginxのおかげで、シェア率の低下が進むApacheですが。。。ぜんぜん使える子なんだからねっ!
prefork MPM の初期値について
apache2.4系の初期値は以下になります。
apache2.2系は、
MaxRequestWorkers → MaxClients
MaxConnectionsPerChild → MaxRequestsPerChild
で置き換えてください。
StartServers 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 256
MaxRequestWorkers 256
MaxConnectionsPerChild 10000
prefork - Apache HTTP サーバ バージョン 2.4で、以下のように書かれています。
このMPMは非常に自律的なので、このMPMの設定ディレクティブを調整する必要はほとんどないでしょう。もっとも重要なことは、MaxClientsが、予想される同時リクエスト数を十分扱えるぐらいは大きいけれども、全プロセスに十分な物理メモリが確実に行き渡る程度には小さい値にする、ということです。
よく理解もせずに、この数値をいろいろいじったのはいい思い出です。
実際、勘所がわかった頃には、月数百万PV程度のPHPサイトであれば、メモリ1GBのサーバで、ほぼ初期値で運用できてました。
ただ、その程度のメモリですと、MaxRequestWorkersが256到達前に悲鳴あげますので、それなりの値に変えると同時に、KeepAliveTimeoutについても考慮が必要です。
※誤解のないように書いておきますが、アクセス数だけで判断せず、要件や体制など、総合的な判断で適切なサーバ構成にしてくださいね。
KeepAliveTimeoutについて
KeepAliveはデフォルトで『On』です。理由がない限りは『On』のままで利用することが多いかと思います。そこでKeepAliveTimeoutについてです。
KeepAliveTimeoutの初期値は『5』です。持続的な接続で次のリクエストが来るまでサーバが待つ時間、つまり、プロセスが5秒間占有されます。
もう使わないプロセスだったとしても、5秒間はプロセスが居残り、その分のメモリが消費されている状態になります。
サーバのメモリが不十分な場合は、たとえば、KeepAliveTimeoutを『2』にする事で、プロセス数が減って、メモリ不足が解消できるかもしれません。
逆にKeepAliveTimeoutを減らす事で、逆にプロセス数が多くなるような場合は、適正な値を探ってください。
MaxRequestWorkersの適正値を探る
まずは、Apacheが使えるメモリの総量(メモリの空き容量)がどのくらいか調べます。わかりやすいサイトがあったので、詳しくはそちらをご覧ください。
【RHEL】linuxメモリのfreeとmeminfoの関係を図解し利用率の計算方法を説明してみる
次にApacheの子プロセスが、どのくらいメモリを喰うか調べます。これもわかりやすいサイトがありましたので、詳しくはそちらをご覧ください。
メモリの共有分を考慮してApacheのメモリ使用量を割り出す
- CentOS 7.6
- Apache 2.4.35
- PHP 7.3.0
- MariaDB 10.2.20
- メモリ 1GB
上記の環境で、小規模なシステムを設置して、プロセスを増やして計測すると、
Apache(子プロセス)が使えるメモリ=570MB
プロセス占有メモリ平均=3MB
でした。
実際に運用していくと、570MB全てがApacheに使えるわけではないので、仮に510MBとすると、
510 ÷ 3 = 170
なんて数字が出せたりします。
MaxRequestWorkersの適正値を探るにあたり、多少の指針にはなりそうです。
本題の設定を晒す
『40万PV/1時間』をサーバ1台で捌いた当時の設定
- CentOS 6.3
- PHP 5.3
- Apache 2.2
- メモリ 32GB
<IfModule prefork.c>
StartServers 30
MinSpareServers 20
MaxSpareServers 70
ServerLimit 5200
MaxClients 5200
MaxRequestsPerChild 4000
</IfModule>
KeepAliveTimeout 3
MaxClientsの値を5200にしてますが、普通にこれ書くと怒られます。
実はCentOS 6(RHEL6)のデフォルトのプロセス最大数(ulimit)が1024に設定されているからなんです。(RHEL7はデフォ4096)
というわけで、ulimitの設定が必要なのですが、わかりやすい説明がされているサイトがありましたので、詳しくはそちらをご覧ください。
httpdプロセス数の上限を、ulimitを設定して増やせるようにする方法
この晒しが参考になって、幸せになれる人がいたら嬉しいです。