Apacheのパフォーマンスは、同時リクエスト数が256を超えると劇的に低下します


14

サイトの更新後、週に1回訪問者が急増する比較的トラフィ​​ックの少ないサイトを運営しています。このスパイクの間、サイトのパフォーマンスは週の残りの期間に比べて非常に低くなります。サーバーの実際の負荷は非常に低く、CPU 10%未満、RAM 30%未満で確実に維持されます(ハードウェアは実際に行っていることに対して完全に過剰である必要があります)が、何らかの理由でApacheはその量に対処できないようですリクエストの。RHEL 5.7、カーネル2.6.18-274.7.1.el5、x86_64でapache 2.2.3を実行しています。

abを使用して営業時間外にこの動作を再現しようとすると、約256人のユーザーを超えると、パフォーマンスが大幅に低下します。私が思いつく可能性のある最小のユースケースでテストを実行すると(静的テキストファイルが取得され、合計223バイト)、245の同時リクエストで一貫してパフォーマンスが正常になります。

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       15   25   5.8     24      37
Processing:    15   65  22.9     76      96
Waiting:       15   64  23.0     76      96
Total:         30   90  27.4    100     125

Percentage of the requests served within a certain time (ms)
  50%    100
  66%    108
  75%    111
  80%    113
  90%    118
  95%    120
  98%    122
  99%    123
 100%    125 (longest request)

しかし、最大265の同時要求をラチェットするとすぐに、それらのサブセットが完了するまでに途方もない時間を要し始めます。

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       13  195 692.6     26    3028
Processing:    15   65  21.3     72     100
Waiting:       15   65  21.3     71      99
Total:         32  260 681.7    101    3058

Percentage of the requests served within a certain time (ms)
  50%    101
  66%    108
  75%    112
  80%    116
  90%    121
  95%   3028
  98%   3040
  99%   3044
 100%   3058 (longest request)

これらの結果は、複数の実行にわたって非常に一貫しています。そのボックスに向かう他のトラフィックがあるので、ハードカットオフがある場合はどこにあるのか正確にはわかりませんが、疑わしいことに256に近いようです。

当然、これはpreforkのスレッド制限が原因であると想定していたため、使用可能なスレッド数を2倍にし、スレッドプールが不必要に拡大および縮小しないように構成を調整しました。

<IfModule prefork.c>
StartServers     512
MinSpareServers  512
MaxSpareServers  512
ServerLimit      512
MaxClients       512
MaxRequestsPerChild  5000
</IfModule>

mod_statusは、512個の使用可能なスレッドで実行していることを確認します

8 requests currently being processed, 504 idle workers

ただし、265の同時リクエストを試行しても、以前とほぼ同じ結果が得られます

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       25  211 714.7     31    3034
Processing:    17   94  28.6    103     138
Waiting:       17   93  28.5    103     138
Total:         57  306 700.8    138    3071

Percentage of the requests served within a certain time (ms)
  50%    138
  66%    145
  75%    150
  80%    161
  90%    167
  95%   3066
  98%   3068
  99%   3068
 100%   3071 (longest request)

ドキュメント(およびStack Exchange)を精査した後、このボトルネックに対処しようとするさらなる構成設定に途方に暮れています。私が見逃しているものはありますか?Apache以外の回答を探し始める必要がありますか?他の誰かがこの動作を見ましたか?どんな助けも大歓迎です。

編集:

Ladadadadaのアドバイスに従って、私はapacheに対してstraceを実行しました。-ttと-Tを数回試してみましたが、異常なものは見つかりませんでした。次に、現在実行中のすべてのApacheプロセスに対してstrace -cを実行してみましたが、次のようになりました。

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 22.09    0.317836           5     62128      4833 open
 19.91    0.286388           4     65374      1896 lstat
 13.06    0.187854           0    407433           pread
 10.70    0.153862           6     27076           semop
  7.88    0.113343           3     38598           poll
  6.86    0.098694           1    100954     14380 read

(...アブドリッジ)

私がこの権利を読んでいる場合(そしてstraceをあまり頻繁に使用しないので我慢してください)、これらのリクエストにかかっている時間を説明できるシステムコールはありません。リクエストがワーカースレッドに到達する前にボトルネックが発生しているように見えます。

編集2:

何人かの人々が示唆したように、私はWebサーバー自体でテストを再度実行しました(以前はテストは中立的なインターネットの場所から実行されていました)。結果は驚くべきものでした:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   11   6.6     12      21
Processing:     5  247 971.0     10    4204
Waiting:        3  245 971.3      7    4204
Total:         16  259 973.3     21    4225

Percentage of the requests served within a certain time (ms)
  50%     21
  66%     23
  75%     24
  80%     24
  90%     26
  95%   4225
  98%   4225
  99%   4225
 100%   4225 (longest request)

最終的な時間はインターネットベースのテストに似ていますが、ローカルで実行すると一貫して少し悪くなるようです。さらに興味深いことに、プロファイルは劇的に変化しました。長時間実行されるリクエストの大半が「接続」に費やされる前は、ボトルネックは処理中または待機中のように見えます。これは、実際には以前はネットワークの制限によって隠されていた別の問題である可能性があると疑う余地があります。

Apacheホストと同じローカルネットワーク上の別のマシンからテストを再度実行すると、より妥当な結果が得られます。

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    2   0.8      2       4
Processing:    13  118  99.8    205     222
Waiting:       13  118  99.7    204     222
Total:         15  121  99.7    207     225

Percentage of the requests served within a certain time (ms)
  50%    207
  66%    219
  75%    220
  80%    221
  90%    222
  95%    224
  98%    224
  99%    225
 100%    225 (longest request)

これらの2つのテストを組み合わせていくつかの質問が発生しますが、それとは別に、一定量の負荷の下で発生するある種の深刻なネットワークボトルネックについて、説得力のあるケースを作成する必要があります。次のステップでは、ネットワーク層を個別に調査すると思います。


考慮すべきオプション:CloudFlare、drupal.org / project / boost、CDN、ニスキャッシュ。
ceejayoz

HTTPリクエストを処理する以外に、このサーバーが何をしているのか(実世界)については何も伝えていません。データベース(またはロック競合の影響を受ける可能性のある他の一般的なリソース)が関係していますか?正確に 256のリクエスト(255でOK)で問題が突然発生した場合、おそらく外部リソースが圧倒されている可能性があります。(静的なページを提供するあなたのジャンプがあまりにも間違いなく異常である-そこにいくつかのデバッグのヒントについてLadadadadaの回答を参照してください)
voretaq7

ceejayoz:提案に感謝しますが、基本的には、Apacheをこれほど遅くすべきではないと考えています。問題の影響を軽減するためにできることはたくさんありますが、修正するか、少なくともそれを理解したいと思います。
cmckendry

voretaq7:典型的なリクエストにはphp / mysqlが関係するため、最初はこれらと同じ方針に沿って考えていましたが、完全に静的なコンテンツを提供する場合でも問題は同じしきい値のままです。
cmckendry

1
これは実サーバーですか、それとも仮想マシンですか?ローカルホスト、ローカルネットワーク、またはインターネットからテストを行いますか?100msの範囲の最小応答時間は、インターネットからのテストを示唆しています。ローカルホストからテストしてみてください-おそらくあなたのプロバイダーがあなたを絞っているだけです。
トメツキー

回答:


4

この状況で私がすることは実行されます

strace -f -p <PID> -tt -T -s 500 -o trace.txt

遅い応答の1つをキャプチャするまで、abテスト中にApacheプロセスの1つで。次に、目を通してくださいtrace.txt

-ttおよび-Tオプションは、低速のものを識別するために、各システムコールの開始と持続時間のタイムスタンプを与えます。

open()またはなどの低速のシステムコールを1つ見つけるか、その直後にstat()(場合によっては複数の)コールを含むクイックコールを見つけることができますpoll()。ファイル接続またはネットワーク接続で動作しているものを見つけた場合(かなり可能性が高い)、そのファイルまたは接続ハンドルが見つかるまでトレースを逆方向に見てください。その同じハンドルに対する以前の呼び出しは、何poll()が待っていたのかを知るはずです。


-cオプションを見てください。あなたがトレースしていたApacheの子が、その間に遅いリクエストの少なくとも1つを処理したことを確認しましたか?(straceすべての子で同時に実行する以外に、これをどのように行うかはわかりません。)

残念ながら、strace実行中のプログラムが何をしているのかを完全に把握することはできません。システムコールのみを追跡します。カーネルに何かを要求する必要のないプログラムの内部では、多くのことが起こります。これが発生しているかどうかを判断するには、各システムコールの開始のタイムスタンプを調べます。重大なギャップが見られる場合、そこが時が来ています。これは簡単に削除できず、とにかくシステムコール間に常に小さなギャップがあります。

CPU使用率が低いままであると言ったので、おそらくシステムコールの間に過剰なことは起きていませんが、チェックする価値があります。


からの出力をより詳しく見るとab

応答時間の突然のジャンプ(150ミリ秒から3000ミリ秒の間に応答時間がないように見えます)は、約256の同時接続を超えるとトリガーされる特定のタイムアウトがあることを示唆しています。RAMまたはCPUサイクルが通常のIOで不足している場合、よりスムーズな劣化が予想されます。

第二に、遅いab応答は、3000msがconnectフェーズに費やされたことを示しています。それらのほぼすべてが約30ミリ秒かかりましたが、5%は3000ミリ秒かかりました。これは、ネットワークに問題があることを示しています。

どこabから走っていますか?Apacheマシンと同じネットワークから試すことができますか?

より多くのデータを取得tcpdumpするには、接続の両端で実行して(ntp2つのキャプチャを同期できるように両端で実行することをお勧めします)、tcp再送信を探します。Wiresharkは、tcpの再送信を異なる色で強調表示し、見つけやすくするため、ダンプの分析に特に適しています。

また、アクセスできるネットワークデバイスのログを調べる価値があるかもしれません。最近、ファイアウォールの1つで問題が発生しました。この問題では、帯域幅をkb / sで処理できましたが、受信中の1秒あたりのパケット数を処理できませんでした。毎秒140,000パケットで最高に達しました。ab実行中の簡単な計算により、毎秒約13,000パケットが表示されていたと思われます(遅い要求の5%を無視します)。たぶんこれはあなたが到達したボトルネックです。これが256前後で発生するという事実は、単なる偶然かもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.