web-dev-qa-db-ja.com

高負荷Apacheサーバーのパフォーマンスチューニング

(私たちにとって)負荷の高いWebサーバーで見られるサーバーパフォーマンスの問題を理解しようとしています。環境は次のとおりです。

  • Debian Lenny(すべての安定したパッケージ+セキュリティアップデートにパッチを適用)
  • Apache 2.2.9
  • PHP 5.2.6
  • Amazon EC2ラージインスタンス

私たちが見ている振る舞いは、ウェブは通常応答性があるように感じますが、リクエストの処理を開始するのに少し遅れがあります-ピーク時のほんの一瞬、時には2-3秒。サーバーの実際の負荷は非常に高いと報告されています-topによって報告されるように、多くの場合10.xxまたは20.xx。さらに、これらの時間(viでさえ)の間、サーバー上で他のものを実行するのは非常に遅いので、負荷は間違いなくそこにあります。奇妙なことに、Apacheは最初の遅延以外は非常に応答性が高いままです。

Preforkを使用して、Apacheを次のように構成しました。

StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0

そしてKeepAliveとして:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

サーバーステータスページを見ると、負荷が高いときでもクライアントの上限に達することはめったになく、通常80〜100の要求と、キープアライブ状態の要求の多くに対応しています。これは、最初のリクエストの遅延を「ハンドラーを待機している」として除外するように指示しますが、私は間違っている可能性があります。

AmazonのCloudWatchモニタリングにより、OSが15を超える負荷を報告している場合でも、インスタンスのCPU使用率は75〜80%であることがわかります。

topからの出力例:

top - 15:47:06 up 31 days,  1:38,  8 users,  load average: 11.46, 7.10, 6.56
Tasks: 221 total,  28 running, 193 sleeping,   0 stopped,   0 zombie
Cpu(s): 66.9%us, 22.1%sy,  0.0%ni,  2.6%id,  3.1%wa,  0.0%hi,  0.7%si,  4.5%st
Mem:   7871900k total,  7850624k used,    21276k free,    68728k buffers
Swap:        0k total,        0k used,        0k free,  3750664k cached

プロセスの大部分は次のようになります。

24720 www-data  15   0  202m  26m 4412 S    9  0.3   0:02.97 Apache2                                                                       
24530 www-data  15   0  212m  35m 4544 S    7  0.5   0:03.05 Apache2                                                                       
24846 www-data  15   0  209m  33m 4420 S    7  0.4   0:01.03 Apache2                                                                       
24083 www-data  15   0  211m  35m 4484 S    7  0.5   0:07.14 Apache2                                                                       
24615 www-data  15   0  212m  35m 4404 S    7  0.5   0:02.89 Apache2            

上記と同時にvmstatからの出力例:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 8  0      0 215084  68908 3774864    0    0   154   228    5    7 32 12 42  9
 6 21      0 198948  68936 3775740    0    0   676  2363 4022 1047 56 16  9 15
23  0      0 169460  68936 3776356    0    0   432  1372 3762  835 76 21  0  0
23  1      0 140412  68936 3776648    0    0   280     0 3157  827 70 25  0  0
20  1      0 115892  68936 3776792    0    0   188     8 2802  532 68 24  0  0
 6  1      0 133368  68936 3777780    0    0   752    71 3501  878 67 29  0  1
 0  1      0 146656  68944 3778064    0    0   308  2052 3312  850 38 17 19 24
 2  0      0 202104  68952 3778140    0    0    28    90 2617  700 44 13 33  5
 9  0      0 188960  68956 3778200    0    0     8     0 2226  475 59 17  6  2
 3  0      0 166364  68956 3778252    0    0     0    21 2288  386 65 19  1  0

そして最後に、Apacheのserver-statusからの出力:

Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers

C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................

私の限られた経験から、私は以下の結論/質問を引き出します:

  • KeepAliveリクエストが多すぎる可能性があります

  • IOがvmstatで待機するのに時間がかかることはありますが、一貫性がなく、それほど多くありません(そうでしょうか?))。これが大きな懸念であるかどうかはわかりませんが、経験が浅いですvmstat

  • また、vmstatでは、いくつかの反復で、処理されるのを待機しているプロセスの数が表示されます。これは、Webサーバーの初期ページ読み込み遅延が、おそらく誤って原因であると考えています。

  • 私たちは静的コンテンツ(75%以上)とスクリプトコンテンツの混合物を提供しており、スクリプトコンテンツは多くの場合かなりプロセッサに負荷がかかるため、2つの間の適切なバランスを見つけることが重要です。長期的には静的を別の場所に移動して両方のサーバーを最適化したいのですが、私たちのソフトウェアは今日その準備ができていません

誰かがアイデアを持っている場合は、追加情報を提供できてうれしいです。もう1つの注意点は、これが高可用性の本番環境のインストールであるため、TweakをTweakの後に作成することには警戒しており、KeepAlive自分自身の値です。

12
futureal

まず、クラウドでの実行についてあまり気にしないことを認めることから始めますが、他の場所での私の経験に基づくと、このWebサーバー構成はかなり低い量のトラフィックを反映していると思います。 runqueueが非常に大きいということは、それを処理するのに十分なCPUが利用できないことを示唆しています。ランキューには他に何がありますか?

許可するキープアライブリクエストが多すぎます

いいえ-keepliveでもパフォーマンスは向上します。最新のブラウザーは、パイプラインを実行するタイミングとリクエストを並列で実行するタイミングを非常にスマートに認識しますが、タイムアウトは5秒であり、[〜#〜 ] lot [〜#〜]待機中のサーバーの数-大きなレイテンシの問題がない限り、これを2〜3に下げることをお勧めします。これにより、実行キューが少し短くなります。

Mod_deflateがまだウェブサーバーにインストールされていない場合は、インストールすることをお勧めします-そして、ob_gzhandler()をPHPスクリプトに追加します。これは、自動として実行できます-先頭に追加:

if(!ob_start("ob_gzhandler")) ob_start();

(はい、圧縮はより多くのCPUを使用します-しかし、runqueueからサーバーをより速く/少ないTCPパケットを処理することで、全体としてCPUを節約する必要があります-そしてボーナスとして、サイトもより高速です)。

MaxRequestsPerChildに上限を設定することをお勧めします-500のように言います。これにより、どこかでメモリリークが発生した場合に備えて、プロセスのターンオーバーが可能になります。あなたのhttpdプロセスは巨大に見えます-不要なApacheモジュールを削除していることを確認し、適切なキャッシュ情報で静的コンテンツを提供していることを確認してください。

それでも問題が解決しない場合は、おそらくPHPコード内にあります(fastCGIを使用するように切り替えた場合、パフォーマンスに大きなペナルティがなければ、これは明らかです)。

更新

静的コンテンツがページ間であまり変わらない場合は、以下を試してみる価値もあります。

if (count($_COOKIE)) {
    header('Connection: close');
}

PHPスクリプトも。

7
symcbean

W状態のプロセスの数も非常に多いため、非同期リバースプロキシのインストールを検討する必要があります。あなたのApacheプロセスは、ネットワーク上でブロックされている遅いクライアントにコンテンツを送信するのに多くの時間を費やしているようです。 ApacheサーバーのフロントエンドとしてNginxまたはlighttpdを使用すると、W状態のプロセスの数を劇的に減らすことができます。そして、はい、キープアライブ要求の数を制限する必要があります。おそらく、キープアライブをオフにしてみる価値はあります。

ところで、107個のApacheプロセスは22 rpsに対して高すぎます。5個のApacheプロセスだけを使用して100-120 rpsを提供できました。おそらく、次のステップはアプリケーションのプロファイルを作成することです。

4
Alex

Vmstatに2つの行があり、CPU待機時間がかなり長いことを示しています。それらの行の周りに、かなりの数の書き込み(io-bo)とコンテキストの切り替えを行っています。私は何がブロックを書いているのか、そしてその待機を排除する方法を調べます。私は、ディスクIOを改善することで最も改善が見られると思います。 syslogを確認します-非同期で書き込むように設定します。コントローラーの書き込みキャッシュが機能していることを確認します(確認してください-バッテリーの不良の可能性があります)。

キープアライブはパフォーマンスの問題の原因ではありません。キャッシュを前面で実行していない場合は、接続のセットアップにかかる時間を節約できます。 MaxSpareServersを少し上げて、クランチですべてのフォークを待たないようにすることもできます。

1
beans

最初の試みとしてキープアライブをオフにすることを検討する必要があります...

107個のリクエストが処理されたので、MaxSpareServersを設定した値よりも高く保ちます...

静的コンテンツのリバースプロキシとしての長期nginxでのIMHOを考慮する必要があります

0
evcz

最初の提案:キープアライブを無効にします。パフォーマンスが向上した特定の状況を特定できた場合にのみ必要でしたが、一般にキープアライブを有効にすると、リクエスト数/秒が減少しました。

2番目の提案:MaxRequestsPerChildを設定します。ここでsymcbeanをエコーし​​ます。これは、メモリリークが発生した場合のプロセスのロールオーバーに役立ちます。 500が良い出発点です。

3番目の提案:MaxClientsを増やします。このための大まかな計算は、(物理メモリ-非httpdプロセスで使用されるメモリ)/各httpdプロセスのサイズです。 httpdのコンパイル方法に応じて、この数は最大で255になります。公開サーバーがシステムをクロールするgoogle/yahoo/MSを処理するために250を使用します。

4番目の提案:MaxSpareServersを増やします:MinSpareServersの4〜5倍など。

これらの提案が失敗した場合を除き、DBのリバースプロキシまたはmemcacheを使用した負荷分散について検討します。

0
Paul S