2013-11-04 6 views
15

질문 "Gevent pool with nested web requests"this answer에 코멘트에 내 질문에 이어 :gevent : 많은 양의 산란을 산란시키는 단점?

가정 하나, 동시에 그들 모두를 생성하는 gevent.spawn (...)를 사용하여 어떤 단점은 작업의 큰 숫자가있다 gevent pool과 pool.spawn (...)을 사용하는 것보다 동시에 greenlets 수를 제한 할 수 있습니까?

다르게 공식화 : 문제가 해결되지 않아도 gevent.Pool을 사용하여 "동시성을 제한하는"이점이 있습니까?

이 문제에 대해 "많은 수"를 구성하는 아이디어가 있습니까?

+0

, 내 프로그램은 두 가지 오류를 교대로 유지 'Gevent '시행 착오로 최적의 풀 크기를 찾은 후에 모든 것이 해결되었습니다. 그것은 동시성을 제한하는 이점으로 사용되었습니다. 또한'gevent.spawn()'과 반대로'pool.spawn()'을 사용하여 전체 시간을 줄였습니다. – Spade

답변

18

많은 것들을 다룰 때 더 깨끗하고 좋은 습관입니다. 나는 몇 주 전 DNS를 상대로 30k의 순서로 이메일을 확인하기 위해 gevent spawn을 사용했다.

from gevent.pool import Pool 
import logging 
rows = [ ... a large list of stuff ...] 
CONCURRENCY = 200 # run 200 greenlets at once or whatever you want 
pool = Pool(CONCURRENCY) 
count = 0 

def do_work_function(param1,param2): 
    print param1 + param2 

for row in rows: 
    count += 1 # for logging purposes to track progress 
    logging.info(count) 
    pool.spawn(do_work_function,param1,param2) # blocks here when pool size == CONCURRENCY 

pool.join() #blocks here until the last 200 are complete 

내 테스트에서 발견되는 동시성 내 컴퓨터의 부하가 EC2의 m1.small에 약 1를 가져 할 때 (200)가 주위 때. 나는 조금이라도 순진하게 해냈다. 다시 해보려면 여러 개의 풀을 실행하고 NIC과 CPU의로드를보다 균등하게 분배하려고 잠시 시간을 잤다.

마지막으로주의해야 할 점은 열려있는 파일을 주시하고 필요할 경우 파일 크기를 늘리는 것입니다 (http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files). 제가 실행하고있는 그린렛은 그린렛 당 약 5 개의 파일 설명자를 사용하고 있었기 때문에 조심하지 않으면 꽤 빨리 다 쓸 수 있습니다. 시스템 부하가 1보다 높으면 아무리 유용해도 도움이되지 않을 수 있습니다.

5

Google에서 여기 와서 몇 가지 간단한 테스트를 실행하여 숫자가 증가하는 N을 낳습니다.

# 1 greenlet 
real 0m1.032s 
user 0m0.017s 
sys  0m0.009s 

# 100 greenlets 
real 0m1.037s 
user 0m0.021s 
sys  0m0.010s 

# 1,000 greenlets 
real 0m1.045s 
user 0m0.035s 
sys  0m0.013s 

# 10,000 greenlets 
real 0m1.232s 
user 0m0.265s 
sys  0m0.059s 

# 100,000 greenlets 
real 0m3.992s 
user 0m3.201s 
sys  0m0.444s 

그래서 최대 1,000 greenlets 및 성능 손실이 작은, 그러나 당신이 10,000 greenlets 타격 시작하면, 모든 속도가 느려 : 결과를 공유 그들은 동료 수색자에 유용 할 수있다.

테스트 코드 : '('이 작업은 영원히 차단하는 것 '`gevent.hub.LoopExit : greenlets의 많은 수를 생성하기 위해 풀을 사용하지 않을 경우

import gevent 

N = 0 

def test(): 
    gevent.sleep(1) 

while N < 1000: 
    N += 1 
    gevent.spawn(test) 

gevent.wait()