2013-11-04 4 views
15

सवाल "Gevent pool with nested web requests" को this answer टिप्पणी में मेरे सवाल से इसे जारी रखते हुए:गीवेंट: ग्रीनलेट की बड़ी संख्या में वृद्धि करने के लिए नकारात्मक?

मान लिया जाये कि एक है कार्यों की एक बड़ी संख्या है, वहाँ gevent.spawn (...) का उपयोग कर एक साथ उन सभी को अंडे देने के लिए के लिए किसी भी नकारात्मक पक्ष यह है एक gevent पूल और पूल का उपयोग करने के बजाय। spawn (...) समवर्ती greenlets की संख्या को सीमित करने के लिए?

अलग-अलग फॉर्मूलेटेड: क्या एक gevent के साथ "समेकन सीमित" करने का कोई फायदा है। समस्या को सुलझाने के लिए भी आवश्यक नहीं है?

कोई भी विचार इस मुद्दे के लिए "बड़ी संख्या" का गठन करेगा?

+0

पूल का उपयोग कर greenlets की एक बड़ी संख्या अंडे देने के लिए नहीं है, मेरे कार्यक्रम दो त्रुटियों के बीच बारी-बारी से रखा ('इस आपरेशन हमेशा के लिए ब्लॉक होता है',' और 'Gevent 'परीक्षण और त्रुटि द्वारा इष्टतम पूल आकार के बाद सबकुछ हल हो गया। अभी भी मेरे लिए तर्कहीन है, लेकिन ध्यान देगा यह समेकन सीमित करने का एक लाभ के रूप में है। इसके अलावा, मैंने 'gevent.spawn() 'के विपरीत' pool.spawn() 'के साथ कम होने के लिए कुल समय मापा। – Spade

उत्तर

18

बहुत सारी चीजों से निपटने के दौरान यह केवल क्लीनर और एक अच्छा अभ्यास है। मैं कुछ हफ्ते पहले इसमें भाग गया था, मैं 30k के आदेश पर DNS के खिलाफ ईमेल का एक समूह सत्यापित करने के लिए 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 

मैं अपने परीक्षण में पाया गया कि जब संगामिति लगभग 200 है जब मेरे मशीन लोड एक EC2 m1.small पर लगभग 1 मंडराना होता था। मैंने इसे थोड़ा सा मूर्खतापूर्ण किया, हालांकि, अगर मैं इसे फिर से करना चाहता हूं तो मैं कई पूल चलाऊंगा और एनआईसी और सीपीयू पर लोड को समान रूप से वितरित करने की कोशिश करने के लिए उनके बीच कुछ समय सो जाऊंगा।

ध्यान में रखने के लिए एक आखिरी बात यह है कि आपकी खुली फाइलों पर नजर रखें और यदि आवश्यकता हो तो बढ़ाना: http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files। मैं जो ग्रीनलेट चला रहा था वह प्रति हरे रंग के लगभग 5 फाइल डिस्क्रिप्टर ले रहा था ताकि यदि आप सावधान नहीं हैं तो आप बहुत तेज़ी से बाहर निकल सकते हैं। यह उपयोगी नहीं हो सकता है यदि आपका सिस्टम लोड एक से ऊपर है क्योंकि आप कम किए गए रिटर्न को देखना शुरू कर देंगे।

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 

तो 1000 greenlets और प्रदर्शन नुकसान छोटे है, लेकिन एक बार आप 10,000+ greenlets मार शुरू करते हैं, सब कुछ धीमा।

टेस्ट कोड: `gevent.hub.LoopExit:

import gevent 

N = 0 

def test(): 
    gevent.sleep(1) 

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

gevent.wait() 
संबंधित मुद्दे