Apache2.2のパフォーマンスチューニング(その1)

投稿者: | 2011年2月27日
Pocket

対象サーバについて

製品名 OpenBlockS 600
OS(kernel ver) Debian lenny(2.6.29)
CPU 600MHz(AMCC PowerPC 405EX)
メモリ 1GB(DDR2 SDRAM)
ストレージ 8GB(Compact Flash)

はじめに

Apache2.2の基本設定、バーチャルホスト設定、ログ設定等はApache2.2の設定にまとめていますので参照してみて下さい。

また、MaxclientsについてはApache2.2のパフォーマンスチューニング(その2)にまとめています。

使用しているMPMと設定の確認

Apacheで代表的なMPM(Multi Processing Module)としては以下の二つがあります。

prefork あらかじめ複数のプロセスを生成してクライアントの接続に備えるマルチプロセスモデル
worker マルチスレッドとマルチプロセスのハイブリッド型

マルチスレッドであるworkerの方が、スレッドがメモリ空間を共有していたり、スレッド切り替え時にメモリ共有しているため切り替えのためのコストが少ない等などの理由によりお勧めのようですが、本サイトのように大量のアクセスがあるわけではない環境ではどちらを採用してもあまりかわらなそうです(ちなみにマルチプロセス、マルチスレッドの比較についてはLinuxネットワークプログラミング(シングルプロセス、シングルスレッドで多重化)にも書いています)。

とはいえ、preforkかworkerかでMaxClients関連の設定箇所が変わってきますので、まずApacheがPreforkとWorkerのどちらで動作しているのかを調べます。以下のように、当サイトではpreforkで動作していることが分かります。

www:~# apache2ctl -l
Compiled in modules:
... 
  prefork.c
...

PHPを動かす環境ではworkerでなくpreforkを使用すべきようです(PHPのサイトを参照)そういえば、phpをインストールした際にapache2-mpm-workerが削除され、apache2-mpm-preforkがインストールされていた記憶があったので、ログを読み返してみたところ形跡が残っていました。

# aptitude install apache2
以下の新規パッケージがインストールされます:
  apache2 apache2-mpm-worker{a} apache2-utils{a} apache2.2-common{a} libapr1{a} libaprutil1{a} libexpat1{a}

# aptitude install php5
以下の新規パッケージがインストールされます:
  apache2-mpm-prefork{a} libapache2-mod-php5{a} php5 php5-common{a}
以下のパッケージが削除されます:
  apache2-mpm-worker{a}

Apache2におけるpreforkの独自設定箇所を確認します。

www:~# less /etc/apache2/apache2.conf

...

<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

これらの値をチューニングしていきますが、MaxClientsは長くなるので、別途Apache2.2のパフォーマンスチューニング(その2)にまとめるとして、本記事ではMaxClients以外の4つのパラメータ(StartServers、MinSpareServers、MaxSpareServers、MaxRequestsPerChild)に絞って解説します。

StartServers/MinSpareServers/MaxSpareServers

MinSpareServers/MaxSpareServersについては混んでいるサイト以外あまりいじるべきではないとApacheのサイトに記載があります。また、StartServersもApacheのサイトに「通常はこの値を調整する理由はあまりないでしょう」と記載があります。とはいえ挙動については把握しておきたいので、パラメータを調整した際の動作について確認してみたいと思います。

まずはps auxでapacheのプロセス数を見てみます。

# ps aux | grep apache
root     21759  0.0  1.0  71052 10604 ?        Ss   Jan07   1:05 /usr/sbin/apache2 -k start
www-data   683  0.4  1.7  73516 18476 ?        S    23:26   0:04 /usr/sbin/apache2 -k start
www-data   684  0.2  1.3  72592 14124 ?        S    23:27   0:01 /usr/sbin/apache2 -k start
www-data   685  0.4  1.3  72464 13900 ?        S    23:28   0:03 /usr/sbin/apache2 -k start
www-data   686  0.4  1.3  72720 14060 ?        S    23:28   0:04 /usr/sbin/apache2 -k start
www-data   687  0.6  1.3  73516 14388 ?        S    23:28   0:05 /usr/sbin/apache2 -k start
www-data 20881  0.6  2.0  73812 21008 ?        S    20:43   1:06 /usr/sbin/apache2 -k start
www-data 29062  0.6  1.8  71948 19540 ?        R    22:52   0:20 /usr/sbin/apache2 -k start
www-data 29069  0.1  1.7  71932 17992 ?        S    22:52   0:03 /usr/sbin/apache2 -k start
www-data 29092  0.2  1.8  73628 18916 ?        S    22:57   0:05 /usr/sbin/apache2 -k start
www-data 29101  0.2  1.6  72508 17436 ?        S    22:59   0:06 /usr/sbin/apache2 -k start

まずps auxで確認してみたところ、STATがS(待機状態)の子プロセス(rootが親プロセス)が10個ありました。

StartServers

Apache2.2のサイトより引用

StartServers ディレクティブは、 起動時に生成される子サーバプロセスの数を設定します。 プロセス数は負荷に応じて動的に制御されますので、 通常はこの値を調整する理由はあまりないでしょう。

# /etc/init.d/apache2 restart
Restarting web server: apache2 ... waiting .

# ps aux | grep apache
root       753  8.3  0.9  71052  9460 ?        SNs  23:44   0:00 /usr/sbin/apache2 -k start
www-data   759  0.0  0.4  71052  4340 ?        SN   23:44   0:00 /usr/sbin/apache2 -k start
www-data   760  0.0  0.4  71052  4340 ?        SN   23:44   0:00 /usr/sbin/apache2 -k start
www-data   761  0.0  0.4  71052  4340 ?        SN   23:44   0:00 /usr/sbin/apache2 -k start
www-data   762  0.0  0.4  71052  4340 ?        SN   23:44   0:00 /usr/sbin/apache2 -k start
www-data   763  0.0  0.4  71052  4340 ?        SN   23:44   0:00 /usr/sbin/apache2 -k start

→Apacheを再起動したところ5つになりました。

MinSpareServers

Apache2.2のサイトより引用

MaxSpareServers ディレクティブは、 アイドルな子サーバプロセスの希望最小個数を設定します。 アイドルプロセスとは、リクエストを扱っていないプロセスです。 MinSpareServers よりも少ない数がアイドルであれば、 親プロセスは最高で 1 秒につき 1 個の割合で新しい子プロセスを生成します。

apache2.confのMinSpareServers/MaxSpareServersを以下の通り修正してみます。


# less /etc/apache2/apache2.conf
<IfModule mpm_prefork_module>
    StartServers          3
    MinSpareServers       6
    MaxSpareServers       8
    MaxClients           50
    MaxRequestsPerChild  1024
</IfModule>

# /etc/init.d/apache2 restart
Restarting web server: apache2 ... waiting ..

起動直後のプロセス状態は以下の通りでした。

# ps aux | grep apache
root      1173 12.5  0.9  71052  9460 ?        SNs  00:05   0:00 /usr/sbin/apache2 -k start
www-data  1179  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1180  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1181  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1182  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start

→StartServers(3個)からMinSpareServers(6個)まで生成されている途中段階のため4つあるのだと思われます。

しばらくして再度確認します。

# ps aux | grep apache
root      1173  8.3  0.9  71052  9460 ?        SNs  00:05   0:00 /usr/sbin/apache2 -k start
www-data  1179  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1180  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1181  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1182  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1185  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
www-data  1186  0.0  0.4  71052  4340 ?        SN   00:05   0:00 /usr/sbin/apache2 -k start
root      1188  0.0  0.0   3316   916 pts/0    SN+  00:05   0:00 grep apache

→MinSpareServersの6つまで増えていました。

MaxSpareServers

Apache2.2のサイトより引用

MaxSpareServers ディレクティブは、 アイドルな子サーバプロセスの希望最大個数を設定します。 アイドルプロセスとは、リクエストを扱っていないプロセスです。 MaxSpareServers よりも多い数がアイドルであれば、 親プロセスは超過プロセスを kill します。

通常はabコマンド等を使用するのでしょうが、ここではとりあえずブラウザからサイトに大量アクセスした後、プロセス状態を確認します。

# ps aux | grep apache
root      1173  0.0  0.9  71052  9472 ?        SNs  00:05   0:00 /usr/sbin/apache2 -k start
www-data  1179  0.9  1.5  72904 16032 ?        RN   00:05   0:04 /usr/sbin/apache2 -k start
www-data  1181  1.3  1.4  72912 15172 ?        RN   00:05   0:05 /usr/sbin/apache2 -k start
www-data  1185  0.6  1.3  72564 14408 ?        RN   00:05   0:02 /usr/sbin/apache2 -k start
www-data  1186  0.2  1.3  72564 13712 ?        SN   00:05   0:01 /usr/sbin/apache2 -k start
www-data  1199  0.6  1.3  72564 14248 ?        RN   00:05   0:02 /usr/sbin/apache2 -k start
www-data  1224  2.2  1.5  72500 16072 ?        SN   00:09   0:02 /usr/sbin/apache2 -k start
www-data  1225  1.9  1.4  72228 15408 ?        SN   00:09   0:02 /usr/sbin/apache2 -k start
www-data  2576  2.2  1.2  72456 12488 ?        RN   00:11   0:01 /usr/sbin/apache2 -k start
www-data  2809  3.0  1.2  72512 12488 ?        RN   00:11   0:01 /usr/sbin/apache2 -k start
www-data  3283  0.0  0.4  71052  4340 ?        SN   00:11   0:00 /usr/sbin/apache2 -k start
www-data  3285  0.0  0.4  71052  4340 ?        SN   00:11   0:00 /usr/sbin/apache2 -k start
www-data  3286  0.0  0.4  71052  4340 ?        SN   00:11   0:00 /usr/sbin/apache2 -k start

→子プロセスが12個まで増えました(RNがrunning分です。)

# ps aux | grep apache
root      1173  0.0  0.9  71052  9472 ?        SNs  00:05   0:00 /usr/sbin/apache2 -k start
www-data  1179  1.4  1.5  72904 16140 ?        SN   00:05   0:06 /usr/sbin/apache2 -k start
www-data  1181  1.6  1.4  72444 14788 ?        SN   00:05   0:07 /usr/sbin/apache2 -k start
www-data  1185  1.0  1.3  72180 14144 ?        SN   00:05   0:04 /usr/sbin/apache2 -k start
www-data  1199  1.0  1.3  72180 14076 ?        SN   00:06   0:04 /usr/sbin/apache2 -k start
www-data  2576  2.9  1.2  72180 12796 ?        SN   00:11   0:03 /usr/sbin/apache2 -k start
www-data  2809  3.5  1.3  72176 13836 ?        SN   00:11   0:03 /usr/sbin/apache2 -k start
www-data  3285  0.0  0.4  71052  4340 ?        SN   00:11   0:00 /usr/sbin/apache2 -k start
www-data  3286  0.0  0.4  71052  4340 ?        SN   00:11   0:00 /usr/sbin/apache2 -k start

→しばらくして再度確認すると、8個(MaxSpareServers設定値)まで減りました。STATがRのプロセスが消えるわけではない点が少し意外でした。

本サイトではとりあえずApacheサイトに記載のあった通り、元の設定に戻しておきます。

# vi /etc/apache2/apache2.conf

...

<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

Maxclentsについて

長くなるので、別途Apache2.2のパフォーマンスチューニング(その2)にまとめます。

MaxRequestsPerChildについて

Apacheの親プロセスが子プロセスをforkするまでのリクエスト数の設定になります。

リクエスト数が設定した値に達するとforkを行い、親プロセスと子プロセスの共有が100%に戻るため、メモリの効率利用に繋がりますし、メモリリーク防止にもなります。

当サイトの初期設定では、MaxRequestsPerChild = 0 に設定されていましたが、その場合、子プロセスはforkされることなく動作し続けます。

リクエストが多数のサイトでは、値が小さすぎるとプロセスの終了と生成が繰り返されるため、ある程度大きな値にしなければなりませんが、当サイトでは1024ぐらいにして様子を見たいと思います。

www:~# less /etc/apache2/apache2.conf

...

<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
    MaxRequestsPerChild  1024
</IfModule>

次はMaxclientsの設定です。

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です