Edited at

中規模サイトのApacheチューニング

More than 1 year has passed since last update.

イマドキApacheのチューニングなんてしなくてもちゃんと動くだろうと思ってたら痛い目にあったので、書いてます。基本をおろそかにするとよくないですね。

21731ad65f5a1c5459f56a17e58eb544_s.jpg

[追記]

スライドも作ってみました。良かったら見てください。

http://www.slideshare.net/yumemikouda/apache-69549461


前提


  • Apache2.x系です

  • preforkでの起動です

  • 写真はイメージです

  • WEBサーバ数台+DB2台(マスター1、レプリカ1)程度のトラフィックを前提


    • 大規模だとまた話が変わってきます




mpm関連


パラメータ説明

項番
項目
説明
補足

1
StartServers
Apache起動時の子プロセス数
Apache起動時にまずはここで設定された数の子プロセスを起動します

2
MinSpareServers
待機時の最小子プロセス数
子プロセスがMinSpareServersより少なくなったら、この値まで子プロセスを上げます

3
MaxSpareServers
待機時の最大子プロセス数
子プロセスがMaxSpareServersより大きくなったら、この値まで子プロセスを下げます

4
ServerLimit
設定可能なサーバプロセス数の上限
MaxClientsを256以上に設定したい場合はServerLimitも設定する必要があります。また、 MaxClientsの上に書かないと効きません

5
MaxClients
最大の小プロセス数
この数≒最大の同時接続数です

6
MaxRequestsPerChild
1子プロセスが処理するリクエスト数
ここで設定された数のリクエストを処理すると子プロセスが死んで、新しい子プロセスに生まれ変わります。"0"にすると無制限にリクエストを処理します


チューニング


  • 忙しいサイトなら1-5は全て同じ値に設定してしまいましょう

  • どうせ忙しいサイトならMaxClientには達するんだと思います。であれば、変にメモリをケチらずに最初からMaxClientまで子プロセスを起動してしまったほうがレスポンスが良いです

  • 急激なトラフィック増の際に多くの子プロセスが一気に起動することでシステムのロードがスパイクし、レスポンスを返せなくなることがあるからです

  • mod_wsgiとかmod_perlとか読み込んでいる場合は特に子プロセス起動時のオーバーヘッドは馬鹿にできません

  • かといって、MaxRequestsPerChildを"0"にして子プロセスを殺さないようにするのはやめたほうが良いです。子プロセスのメモリ使用量が肥大化し、システムでスワップが発生する可能性があります。


MaxClient数の算出方法


  • サーバの物理メモリを消費し尽くしてスワップさせないことが重要です

  • httpd1プロセスあたりのメモリ使用量はtopコマンドでおおまかに把握することができます


    • topコマンドで表示されるRES(物理メモリ使用量)です

    • 各プロセス毎に処理している内容によりメモリ量の増減がありますので、いくつかのhttpdプロセスをサンプリングしておおまかに平均値を算出しましょう




  • サーバの物理メモリ量 > 上記で算出した1httpdプロセスあたりのメモリ使用量の平均値×MaxClient数+他のプロセスが使うであろうメモリ使用量 となるようにMaxClient数を設定しましょう

top - 17:29:42 up 6 days, 17 min,  4 users,  load average: 0.92, 1.10, 1.23

Tasks: 237 total, 2 running, 235 sleeping, 0 stopped, 0 zombie
Cpu(s): 24.0%us, 0.8%sy, 0.0%ni, 74.7%id, 0.0%wa, 0.0%hi, 0.5%si, 0.1%st
Mem: 15343788k total, 10152612k used, 5191176k free, 231068k buffers
Swap: 0k total, 0k used, 0k free, 2336312k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26835 apache 20 0 328m 59m 6400 R 29.6 0.4 0:48.24 httpd
26870 apache 20 0 331m 62m 5884 S 27.2 0.4 0:42.28 httpd
26607 apache 20 0 317m 49m 5872 S 20.3 0.3 0:25.53 httpd
27481 apache 20 0 316m 48m 5876 S 12.3 0.3 0:36.53 httpd
26730 apache 20 0 317m 48m 5880 S 9.6 0.3 0:34.03 httpd
26583 apache 20 0 320m 51m 5884 S 1.3 0.3 0:32.28 httpd


HTTPタイムアウト


パラメータ説明

項番
項目
説明
補足

1
Timeout
リクエストを受け取ってから処理完了までの待機時間
下記のそれぞれの時間にTimeoutが設定されます。1. GET リクエストを受け取るのにかかる総時間 2. POST や PUTリクエストにおいて、次の TCP パケットが届くまでの待ち時間 3. レスポンスを返す際、TCP の ACK が帰ってくるまでの時間

2
KeepAlive
持続的接続を許可する
HTTPで定義されているKeepAlive接続を有効にする設定。1つのTCP接続で複数のHTTPリクエストが処理されるようになる

3
MaxKeepAliveRequests
持続的接続で許されるリクエスト数
1回のKeepAlive接続で処理可能なリクエスト数

4
KeepAliveTimeout
持続的な接続で次のリクエストを待つ時間
KeepAliveをOnにしていた場合のみ有効


チューニング


  • Timeoutのデフォルト値は300秒ですが、長過ぎますので、短くしましょう。応答のないクライアントを5分も待つやさしさは不要です。我々は忙しいんです

  • KeepAliveは幻想の機能です。忙しいサイトなら使うのやめましょう。忙しくないサイトならどちらでも良いと思います

  • KeepAliveを有効にすれば、たしかに1回の接続でクライアントから複数のリクエストを送ることができるため、TCP接続のオーバーヘッドやコネクション数が抑えられる気がします

  • しかし、それは幻想です。結局、1クライアントから複数のTCPコネクションを張られ、そのコネクションが長時間専有されることで、Apacheの子プロセスをあっという間に消費しつくされてしまいます

  • KeepAliveをOffにしていればMaxKeepAliveRequestsやKeepAliveTimeoutはいくつでもかまわないです

  • 上記のようにKeepAliveは切ったほうが良いですが、AWSのELB配下では切らない方が良いようです → Amazon ELBをうまくつかうには、KeepAliveを有効にしよう。Timeoutは60秒よりだいぶ長くしよう。その背景。


HTTP通信圧縮


パラメータ説明

項番
項目
説明
補足

1
SetOutputFilter
圧縮機能を有効にします。
mod_deflateモジュールを使い圧縮します。フィルタとしてDEFLATEを指定しると圧縮機能が有効になります。

2
AddOutputFilterByType
圧縮対象とするMIMEタイプを指定します。
htmlやcssはもちろんjavascriptなども圧縮しましょう


チューニング


  • PNGやJPEGなどの画像ファイルはすでに圧縮されているため圧縮対象から外すと無駄な圧縮処理をしないですみます

  • 古いブラウザではバグなどにより圧縮対応していないものもあるので無効にします(今どき使ってる人いないと思いますが。。。)

  • 実際のconfの書き方は下記サイトを参考にしてみてください




ログファイル関連


HostnameLookups


  • アクセスをログファイルに記録する際に接続元IPアドレスをDNSで逆引きするオプションです

  • DNSの逆引きは時間がかかることが多いですので、Offにするのは必須です


仲間募集

株式会社スピカでは一緒に切磋琢磨できるエンジニアの方を募集しています!ぜひ、こちらをご覧ください!!