2015-02-06 5 views
1

많은 HTTP 요청을 보내는 앱이 있습니다. 먼저, 이벤트 릿을 사용하여 요청을 구현합니다. 그러나 성능이 너무 낮습니다. 따라서 다중 프로세스를 사용하여 속도를 높일 것으로 예상됩니다. 알아야 할 사항은 서버가 약 200ms (네트워크 전송 제외)의 단일 요청을 처리하는 것입니다.다중 프로세스가 이벤트 릿을 통해 HTTP 요청을 보내는 속도를 올릴 수없는 이유

그러나 다중 프로세스는 원래 버전보다 느립니다. 나는이 결과에 너무 놀란다! 왜?

코드는 다음과 같습니다. timeit을 사용하여 시간을 측정했습니다.

import eventlet 
eventlet.monkey_patch(all=False, socket=True) 

import requests 

URL = 'http://....' 

def send(): 
    pile = eventlet.GreenPile(20) 
    for x in xrange(100): 
     pile.spawn(requests.get, URL) 
    for x in pile: 
     pass 

import multiprocessing 

def main(): 
    procs = [multiprocessing.Process(target=send) for _ in range(3)] 
    for p in procs: 
     p.start() 
    for p in procs: 
     p.join() 

import timeit 

if __name__ == '__main__': 
    print timeit.timeit(main, number=1) 
+0

나는 완전히 코드를 통해 추론 적이 없다,하지만 당신은'병렬 계산을 수행하기 위해 여러 개의 코어를 프로세스 생성을위한 고가의 선행 비용을 가지고 있지만 수 multiprocessing'을 사용하고,에 I/O 바인딩 문제입니다. 병목 현상이 순전히 I/O 인 경우 스레드가 더 나은 솔루션 일 수 있습니다. – zehnpaard

+0

@zehnpaard, 멀티 스레드를 시도해 본 결과 멀티 프로세스와 동일합니다. 그런 결과에 대한 어떤 생각? – Jacky

+0

사실'eventlet.GreenPile'의'spawn'은 녹색 스레드를 생성합니다. 따라서'eventlet'의 맨 위에 스레드 나 프로세스를 사용하는 것이 중복 될 수 있습니다. 서버에 대한 I/O 요청은 이미 병렬로 처리되고 있습니다. – zehnpaard

답변

0

TL : DR : 정보가 충분하지 않습니다. 순수 투기에 의해 서버가 제한 요소 (의도적 인 인위적인 제한이나 리소스 부족으로 인해 발생할 수 있음)이므로 더 많은 동시 요청을 추가하면 평균 속도가 느려집니다.

여기에 대한 이유 중 하나는 클라이언트와 서버 모두에서 시간당 CPU주기, 시간당 메모리 액세스, 메모리 크기, 네트워크 대역폭 등 리소스가 제한되어 있다는 것입니다. OS 및 이벤트 릿은 이러한 자원을 합리적으로 사용합니다. 하나의 요청을하기 위해 필요한 리소스의 양과 소프트웨어가 합리적인 패턴 (선형에 가깝습니다)으로 스케일 아웃 할 수있는 정도를 예측할 수 있습니다. 다중 처리의 이점을 얻으려면 클라이언트 프로세스가 단일 CPU 장치를 100 % 사용 중일 필요가 있습니다. 그리고 구체적으로 requests 라이브러리는 하드웨어 자원을 낭비하는 것으로 잘 알려져 있으며, 시도한 모든 것 (httplib, httplib2, urllib) 중 가장 많은 CPU 오버 헤드를 발생시킵니다. 하지만 병목 현상을 일으키기 위해서는 동시 요청 수를 (수천) 많이 늘리거나 정말 나쁜 CPU를 사용해야합니다. 모든 자원에 대한

  • 여부 HTTP 클라이언트와 서버가 동의 :

    정확한 대답은 정보를 필요로? 나는. 동일한 물리적 하드웨어에서 실행됩니까?

  • 단일 프로세스 모드에서 생성 할 수 있었던 최대 요청 빈도 (초당 횟수)는 얼마입니까? 동시 요청 수를 변경하려면 GreenPile 크기를 조정하십시오.
  • 여러 프로세스를 사용하여 생성 할 수 있었던 요청의 최대 빈도는 얼마입니까? GreenPile 크기와 프로세스 수를 모두 조정하십시오. 멀티 프로세싱없이 여러 독립 Python 인터프리터를 실행 해보십시오.
  • 서버에 병목 현상이 있습니까? 별도의 하드웨어에 다른 클라이언트를 추가하여 확인하십시오. 요청 빈도가 높으면 서버에 병목 현상이 발생하지 않습니다. 클라이언트가 많아지면서 요청 빈도가 떨어지면 서버가 이미 한계에서 실행 중이며 다중 처리는 상황을 악화시키는 데 도움이됩니다.
  • 요청 시간 분포 란 무엇입니까? 220/300/400/500/1000/more ms에서 요청의 몇 퍼센트가 완료 되었습니까?
  • 네트워크 대기 시간/대역폭이란 무엇입니까? 요청/응답 크기 란 무엇입니까? 당신은 그때 네트워크를 포화합니까?

이 질문에 답하면 클라이언트/서버 내부 및 클라이언트/서버간에 일어나는 일에 대해 뛰어난 직관을 얻을 수 있습니다.

관련 Github의 문제 : https://github.com/eventlet/eventlet/issues/195

+0

나는 질문에 하나씩 대답했다. 1. 서버와 클라이언트는 다른 위치에있다. 2. 고정 된 수의 요청을 보내는 데 사용되는 시간은 GreenPile 크기가 10, 20 또는 200이더라도 거의 같습니다. 3. 서버가 1 초 내에 더 많은 요청을 수용 할 수 있습니다. 나는 그것을 테스트 한 apache를 사용했다. ab는 eventlet 버전보다 10 배 더 빠르게 실행할 수있다. 4. 확실하지 않음 5. 요청/응답 크기가 256 바이트보다 작습니다. HTTPS 프로토콜이라는 것입니다. – Jacky

+0

@Jacky 다른 풀 크기로 다음 테스트를 수행하십시오. 100-1000 요청을 실행하고 클라이언트 프로세스의 CPU 사용량을 처음부터 끝까지 측정하십시오. CPU 사용량을 측정하는 방법을 잘 모르는 경우 GNU 시간 (일반적으로/usr/bin/time으로 설치됨) 또는 이벤트 릿 테스트 https://github.com/eventlet/eventlet/blob/master/tests/__init__에서 cpu_usage 함수를 사용할 수 있습니다. 피 # L189 – temoto