ここでは、Apache HTTP Serverのチューニングとベンチマークに関してまとめます。
Apacheのベンチマーク
Apacheの性能はサーバの性能にも左右されますが、Apacheの設定内容によっても変わってきます。
最近のサーバはそこそこ速くなっているので、デフォルト設定のままでもそこそこ速く動いてくれるのですが、それでもアクセス集中対策を考慮するにはサーバのApacheのチューニングも必要になります。
さて、チューニングの方法は説明する前に、性能測定の方法について説明します。
Apacheの性能測定には、ab(Apache Bench)コマンドを使用します。
色々なサイトでも紹介されていますが、基本的なコマンド操作は以下の様になります。
1 |
# ab -n 100 -c 20 http://hogehoge.net/ |
-n 数値 : リクエストの総数
-c 数値 : 同時接続数
指定したURLに対し「リクエストの総数」分のリクエストを行います。並列して接続するため、「同時接続数」を指定することが出来ます。
試しにabコマンドを叩いてみます。(URLは適当です。)
※絶対に他人のサイトを指定しないでください。DoS攻撃とみなされる可能性があります。負荷試験の一種なので、対象のサーバに高負荷を与えることになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 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などで開いて編集してください。
こちらがデフォルト状態の設定状態です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
## ## 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> |
こちらが設定変更後の値です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
## ## 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> |
StartServers | 1 | 起動時に生成される子サーバの数 |
MinSpareServers | 1 | アイドル状態で待機している 子サーバの最小数 |
MaxSpareServers | 5 | アイドル状態で待機している 子サーバの最大数 |
ServerLimit | 10 | MaxClientsに指定できる上限値 |
MaxClients | 10 | 同時接続可能なクライアントの数 |
MaxRequestsPerChild | 4000 | 子サーバが処理できる リクエストの総数 |
デフォルトの状態では、StartServersが「1」になっていたので、最初の接続に掛かる時間が遅くなる傾向にありそうです。
また、MaxClientsが「10」しかないため同時に処理できるリクエストの数が少なく、こちらも処理が遅くなる傾向にあったようです。
変更後の値に設定し、以下のコマンドでWebサーバを再起動します。
1 2 3 4 5 6 7 8 |
【CentOS 6の場合】 # service httpd graceful もしくは # service httpd restart 【CentOS 7の場合】 # systemctl restart httpd |
Webサーバの再起動が完了したら、コマンドを実行して動作を確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# 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で示されたサイトに記載がありますので(英文ですが)、そちらを参考にされることをお勧めします。(本記事が古くなると使えなくなりますが、上記サイトはメンテナンスされていますので)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 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上での計算は難しいかな?