아파치 성능은 ~ 256 개의 동시 요청을 크게 상회


14

사이트 업데이트 후 일주일에 한 번 방문자 수가 급증하는 트래픽이 비교적 적은 사이트를 운영하고 있습니다. 이 급증하는 동안 나머지 주에 비해 사이트 성능이 매우 떨어집니다. 실제로 서버의 부하는 매우 낮고 안정적으로 10 % 미만의 CPU 및 30 % 미만의 RAM (하드웨어가 실제로 수행중인 작업에 대한 완전한 오버 킬이어야 함)을 유지하지만 어떤 이유로 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에 가까운 것으로 보입니다.

당연히, 이것이 프리 포크의 스레드 제한으로 인한 것이라고 가정했기 때문에 사용 가능한 스레드 수를 두 배로 늘리고 스레드 풀이 불필요하게 커지거나 줄어들지 않도록 구성을 조정했습니다.

<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)를 검색 한 후이 병목 현상을 해결하기위한 추가 구성 설정이 손실되었습니다. 내가 놓친 것이 있습니까? 아파치 이외의 답변을 찾기 시작해야합니까? 다른 사람이이 행동을 본 적이 있습니까? 도움을 주시면 감사하겠습니다.

편집하다:

Ladadadada의 조언에 따라, 나는 아파치에 대하여 strace를 달렸다. 나는 -tt와 -T로 몇 번 시도했지만 평범한 것을 찾을 수 없었습니다. 그런 다음 현재 실행중인 모든 아파치 프로세스에 대해 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

(... abdridged)

이 권리를 읽고 있다면 (그리고 자주 strace를 사용하지 않기 때문에 나와 함께 견딜 경우) 시스템 요청 중 어느 것도 이러한 요청에 걸리는 시간을 설명 할 수 없습니다. 요청이 작업자 스레드에 도달하기 전에 병목 현상이 발생하는 것처럼 보입니다.

편집 2 :

여러 사람들이 제안했듯이 웹 서버 자체에서 테스트를 다시 실행했습니다 (이전 테스트는 중립 인터넷 위치에서 실행되었습니다). 결과는 놀랍습니다.

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)

이 두 가지 테스트는 함께 여러 가지 질문을 제기하지만, 그와는 별도로 특정 양의로드에서 발생하는 심각한 네트워크 병목 현상에 대한 강력한 사례가 있습니다. 다음 단계에서는 네트워크 계층을 별도로 조사 할 것이라고 생각합니다.


고려해야 할 옵션 : CloudFlare, drupal.org/project/boost , CDN, Varnish 캐시.
ceejayoz

HTTP 요청을 제공하는 것 외에도이 서버가 수행하는 작업 (실제)에 대해 아무 것도 알려주지 않습니다. 데이터베이스 (또는 잠금 경합이 발생할 수있는 다른 공통 자원)가 있습니까? 정확히 256 개의 요청 (255에서 확인)에서 문제가 갑자기 발생하면 일부 외부 리소스가 늪에 빠졌을 수 있습니다. (- 거기에 몇 가지 디버깅 팁 Ladadadada의 답변을 참조 정적 페이지를 제공 귀하의 점프가 너무 확실히 비정상)
voretaq7

ceejayoz : 제안에 감사하지만 기본적으로 Apache가 느려서는 안된다고 생각합니다. 문제의 영향을 완화하기 위해 할 수있는 일이 많이 있지만 문제를 해결하거나 적어도 이해하고 싶습니다.
cmckendry

voretaq7 : 일반적인 요청에도 php / mysql이 포함되어 있기 때문에 처음에는 동일한 라인을 따라 생각했지만 완전히 정적 콘텐츠를 제공 할 때도 동일한 임계 값으로 문제가 지속됩니다.
cmckendry

1
이것이 실제 서버입니까, 아니면 VM입니까? 로컬 호스트, 로컬 네트워크 또는 인터넷에서 테스트를 수행합니까? 100ms 범위의 최소 응답 시간은 인터넷 테스트를 제안합니다. localhost에서 테스트 해보십시오-아마도 공급자가 당신을 조절하고 있습니다.
Tometzky

답변:


4

이 상황에서 내가 할 일은

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

느린 응답 중 하나를 캡처 할 때까지 ab 테스트 중에 Apache 프로세스 중 하나에서. 그런 다음을 살펴보십시오 trace.txt.

-tt-T옵션을 사용하면 느린 사람을 식별하는 데 도움 시작과 각 시스템 호출의 시간의 타임 스탬프를 제공합니다.

하나의 느린 시스템 호출을 open()stat()거나 poll()그 직후에 (여러 번의) 호출 로 빠른 호출을 찾을 수 있습니다 . 파일이나 네트워크 연결에서 작동하는 것을 찾으면 해당 파일이나 연결 핸들을 찾을 때까지 추적을 거꾸로 살펴보십시오. 동일한 핸들에 대한 이전 호출은 무엇 poll()을 기다리고 있었는지에 대한 아이디어를 제공해야 합니다.


-c옵션을 보는 것이 좋습니다 . 추적중인 Apache 하위가 해당 시간 동안 적어도 하나의 느린 요청을 처리했는지 확인 했습니까? (나는 당신이 어떻게 strace모든 어린이들에게서 동시에 달리는 것 외에는 이것을 확신하지 못합니다 .)

불행히도, strace실행중인 프로그램이 무엇을하고 있는지에 대한 완전한 그림을 우리에게 제공하지는 않습니다. 시스템 호출 만 추적합니다. 커널에 아무것도 요구할 필요가없는 프로그램에서 많은 일이 일어날 수 있습니다. 이러한 상황이 발생하는지 파악하기 위해 각 시스템 호출 시작의 타임 스탬프를 확인할 수 있습니다. 상당한 격차가 보이면 바로 그 시점입니다. 이것은 쉽게 잡을 수 없으며 어쨌든 시스템 호출 사이에 항상 작은 간격이 있습니다.

당신이 CPU 사용량 숙박을 낮게 말했다 때문에, 그건 아마도 시스템 호출하지만, 그것의 가치가 검사 사이에서 일어나는 과도한 일이 없습니다.


의 결과를 자세히 살펴보십시오 ab.

응답 시간의 급격한 증가 (150ms에서 3000ms 사이에 응답 시간이없는 것처럼 보임)는 약 256 개의 동시 연결에서 트리거되는 특정 시간 초과가 발생했음을 나타냅니다. RAM이 부족하거나 CPU주기가 정상 IO 인 경우 성능이 더 저하 될 수 있습니다.

둘째, 느린 ab응답은 3000ms가 connect단계 에서 소비되었음을 나타냅니다 . 거의 모두 30ms 정도 걸렸지 만 5 %는 3000ms 걸렸습니다. 이것은 네트워크가 문제임을 암시합니다.

어디 ab에서가요? Apache 컴퓨터와 동일한 네트워크에서 시도해 볼 수 있습니까?

더 많은 데이터를 들면, 실행 해보십시오 tcpdump(바람직와 연결의 양쪽 끝에서 ntp. 당신은 두 개의 캡처를 동기화 할 수 있도록 양쪽 끝에서 실행) 및 TCP 재전송을 찾습니다. Wireshark는 tcp 재전송을 다른 색상으로 강조 표시하여 찾기가 쉽기 때문에 덤프 분석에 특히 좋습니다.

액세스 할 수있는 모든 네트워크 장치의 로그를 살펴볼 가치가 있습니다. 최근 방화벽 중 하나에서 kb / s로 대역폭을 처리 할 수 ​​있지만 수신하는 초당 패킷 수를 처리 할 수없는 방화벽에 문제가 발생했습니다. 초당 140,000 개의 패킷을 차지했습니다. ab달리기 에 관한 빠른 계산 으로 인해 초당 약 13,000 개의 패킷을 보았을 것입니다 (느린 요청의 5 % 무시). 아마도 이것이 당신이 도달 한 병목 현상 일 것입니다. 이것이 256 주변에서 발생한다는 사실은 순전히 우연의 일치 일 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.