「Webサーバのチューニング」タグアーカイブ

Apache(Webサーバ)のチューニングとベンチマーク

ここでは、Apache HTTP Serverのチューニングとベンチマークに関してまとめます。

Apacheのベンチマーク

Apacheの性能はサーバの性能にも左右されますが、Apacheの設定内容によっても変わってきます。
最近のサーバはそこそこ速くなっているので、デフォルト設定のままでもそこそこ速く動いてくれるのですが、それでもアクセス集中対策を考慮するにはサーバのApacheのチューニングも必要になります。

さて、チューニングの方法は説明する前に、性能測定の方法について説明します。

Apacheの性能測定には、ab(Apache Bench)コマンドを使用します。

色々なサイトでも紹介されていますが、基本的なコマンド操作は以下の様になります。

# ab -n 100 -c 20 http://hogehoge.net/

-n 数値  : リクエストの総数
-c 数値  : 同時接続数

指定したURLに対し「リクエストの総数」分のリクエストを行います。並列して接続するため、「同時接続数」を指定することが出来ます。

試しにabコマンドを叩いてみます。(URLは適当です。)
※絶対に他人のサイトを指定しないでください。DoS攻撃とみなされる可能性があります。負荷試験の一種なので、対象のサーバに高負荷を与えることになります。

# ab -n 600 -c 200 http://hogehoge.net/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking hogehoge.net (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Finished 600 requests


Server Software:        Apache/2.2.15
Server Hostname:        hogehoge.net
Server Port:            80

Document Path:          /
Document Length:        307 bytes

Concurrency Level:      200
Time taken for tests:   4.465 seconds
Complete requests:      600
Failed requests:        0
Write errors:           0
Non-2xx responses:      600
Total transferred:      305400 bytes
HTML transferred:       184200 bytes
Requests per second:    134.39 [#/sec] (mean)
Time per request:       1488.242 [ms] (mean)
Time per request:       7.441 [ms] (mean, across all concurrent requests)
Transfer rate:          66.80 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   11  13.9      1      35
Processing:    58  916 895.7    692    4364
Waiting:       58  916 895.7    692    4364
Total:         75  927 900.7    695    4396

Percentage of the requests served within a certain time (ms)
  50%    695
  66%    752
  75%    777
  80%    819
  90%   1609
  95%   4161
  98%   4193
  99%   4357
 100%   4396 (longest request)

ここで注目したいのは、以下の2点です。
Failed requests: 0
Requests per second: 134.39 [#/sec] (mean)

「Failed requests」でリクエストがフェールになった回数をカウントしています。Failが発生しない様に調整する必要があります。

では、調整の仕方を見ていきましょう。

Apacheのチューニング

Apache 2.2系と2.4系ではチューニングの設定が少し異なります。パラメタの名称が一部変更になっているためです。
以下にそれぞれのパラメタ設定例を示します。
ただし、この設定内容は環境により異なりますので、ご自身のサーバ環境によって値を調整してみてください。

Apache2.2系のチューニングパラメタ

Apache 2.2系のチューニング方法を以下に紹介します。今更感はあるのですが、最も効果的な結果が得られたのがこの環境だったので敢えて事例紹介します。

対象ファイル:/etc/httpd/conf.d/httpd.conf

viなどで開いて編集してください。

こちらがデフォルト状態の設定状態です。

##
## Server-Pool Size Regulation (MPM specific)
##

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers       1
MinSpareServers    1
MaxSpareServers    5
ServerLimit       10
MaxClients        10
MaxRequestsPerChild  4000
</IfModule>

こちらが設定変更後の値です。

##
## Server-Pool Size Regulation (MPM specific)
##

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers       10
MinSpareServers    20
MaxSpareServers    50
ServerLimit       50
MaxClients        50
MaxRequestsPerChild  1000
</IfModule>
StartServers1起動時に生成される子サーバの数
MinSpareServers1アイドル状態で待機している
子サーバの最小数
MaxSpareServers5アイドル状態で待機している
子サーバの最大数
ServerLimit10MaxClientsに指定できる上限値
MaxClients10同時接続可能なクライアントの数
MaxRequestsPerChild4000子サーバが処理できる
リクエストの総数

デフォルトの状態では、StartServersが「1」になっていたので、最初の接続に掛かる時間が遅くなる傾向にありそうです。
また、MaxClientsが「10」しかないため同時に処理できるリクエストの数が少なく、こちらも処理が遅くなる傾向にあったようです。
変更後の値に設定し、以下のコマンドでWebサーバを再起動します。


【CentOS 6の場合】
# service httpd graceful
もしくは
# service httpd restart

【CentOS 7の場合】
# systemctl restart httpd

Webサーバの再起動が完了したら、コマンドを実行して動作を確認してみましょう。

# ab -n 600  -c 200 http://hogehoge.net/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking tech.godpress.net (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Finished 600 requests


Server Software:        Apache/2.2.15
Server Hostname:       hogehoge.net
Server Port:            80

Document Path:          /
Document Length:        317 bytes

Concurrency Level:      200
Time taken for tests:   0.998 seconds
Complete requests:      600
Failed requests:        0
Write errors:           0
Non-2xx responses:      614
Total transferred:      333402 bytes
HTML transferred:       194638 bytes
Requests per second:    601.08 [#/sec] (mean)
Time per request:       332.736 [ms] (mean)
Time per request:       1.664 [ms] (mean, across all concurrent requests)
Transfer rate:          326.17 [Kbytes/sec] received

主要な内容については以下の通りです。

Failed requests: 0
Requests per second: 601.08 [#/sec]

「Requests per second」の値が134.39→601.08に変化しており、1秒間に処理で来ているリクエストの数が大幅にアップ(約4.5倍)しました。

と、ここで問題です。
MaxClientsを適当にしていしましたが、子サーバ(プロセス)が使用するメモリを考慮して計算しないと、実装メモリよりも多くの子サーバが起動してしまうことになってしまいます。
そうなると、スワップ領域まで達し、最終的にもメモリ不足に陥ることになります。
まず、httpdプロセスがどれ位のメモリを使用しているか?そして、PHPを使用しているならば、PHPの利用するメモリも考慮する必要があります。
実際にサーバ上で動作する際に必要となるメモリ量も気に掛かります。

面倒ですよね。
色々な方が作られている様ですが、MaxClientsを自動計算してくれる仕組みがあります。
その方法について、次に説明を行います。

MaxClientsの自動計算

MaxClientsを自動計算する方法について記載します。
Apache Web Service(Webサーバ)は、並列処理を実現するために複数子サーバを起動して、同時に複数のクライアントから要求されるリクエストに対応します。
その最大値をMaxClientsで指定します。

理論的には、httpd(子サーバ)が利用するメモリとPHPが利用するメモリで1つのクライアントから要求される処理を行うとして、システムのメモリを割ることで値が得られる感じです。
この時、システムでそれ以外に使用するメモリも考慮する必要があり、意外と面倒な計算と情報収集を行うこととなります。

それを自動化してくれる仕組みが以下のサイトにあるスクリプトになります。

https://github.com/richardforth/apache2buddy

apache2buddyを利用してMaxClientsを計算させるには、以下のコマンドを実行し、表示される情報を利用します。

コマンドは以下に記していますが、上記のURLで示されたサイトに記載がありますので(英文ですが)、そちらを参考にされることをお勧めします。(本記事が古くなると使えなくなりますが、上記サイトはメンテナンスされていますので)

# curl -sL https://raw.githubusercontent.com/richardforth/apache2buddy/master/apache2buddy.pl | perl
<<あまり見られたくない情報があるので、割愛します。>>
pache2buddy.pl report for server:  (xx.xx.xx.xx):

Settings considered for this report:
[ !! ] *** LOW UPTIME ***.
[ @@ ] The following recommendations may be misleading - apache has been restarted within the last 24 hours.

        Your server's physical RAM:            1024 MB
        Remaining Memory after other services considered: 1016 MB
        Apache's MaxClients directive:  15  <--------- Current Setting
        Apache MPM Model:        prefork
        Largest Apache process (by memory):27 MB
[ !! ]  Your MaxClients setting is too low.
        Your recommended MaxClients setting (based on available memory) is between 33 and 37. <------- Acceptable Range (10% of MAX)
        Max potential memory usage:407 MB
        Percentage of TOTAL RAM allocated to Apache:39.82  %
        Percentage of REMAINING RAM allocated to Apache:40.12  %
--------------------------------------------------------------------------------
A log file entry has been made in: /var/log/apache2buddy.log for future reference.

重要な箇所は以下の一文です。

Your recommended MaxClients setting (based on available memory) is between 33 and 37. <——- Acceptable Range (10% of MAX)

httpdを再起動した直後などは正確な数値が得られない場合がありますので、本来は24時間程度運用した状態で数値を計算することが望ましいです。

上記の例では、MaxClientsの値として33~37が望ましい値として提示されています。

正直、実験を行ったサーバでは、長時間のヒートランを行っていなかったのでこの値が示されましたが、本来であればもっと少ない値が得られるのではないかと思います。

これを元に、先程示したhttpd.confに記載されている以下の値を調整します。

StartServers
MinSpareServers
MaxSpareServers
ServerLimit
MaxClients
MaxRequestsPerChild

最後に、Webサーバの再起動を行えば設定が反映され安定した動作になると思います。こまめにチェックするというよりも、ある程度時間を空けてチェックすると良いと思います。

apache2buddy以外にも自動計算や手動計算の手法が幾つか紹介されています。
自分に合った方法を見つけることが重要です。
今回の手法は、Linux上での手法となります。Windows上での計算は難しいかな?