2015-01-11 5 views
5

सबसे पहले, मेरी बुरी अंग्रेजी के लिए खेद है। मेरी परियोजना में मेरे पास बहुत सारे I/O नेटवर्क अनुरोध हैं। मुख्य डेटा किसी अन्य प्रोजेक्ट में संग्रहीत किया जाता है, और एक्सेस वेब एपीआई (जेएसओएन/एक्सएमएल), मतदान द्वारा प्रदान किया जाता है। हम प्रत्येक एपीआई सत्र (उपयोगकर्ता के बारे में जानकारी प्राप्त करने) के लिए इस एपीआई का उपयोग करते हैं। और कभी-कभी, हमें प्रतिक्रिया की प्रतीक्षा करने में समस्या होती है। हम nginx + uwsgi + django का उपयोग करते हैं। जैसा कि आप जानते हैं, Django तुल्यकालिक (या अवरुद्ध) है। हम नेटवर्क IO प्रतीक्षा के साथ हल समस्या के लिए multithreading के साथ uwsgi का उपयोग करते हैं। मैंने भूगर्भ के बारे में पढ़ने का फैसला किया। मैं सहकारी और प्रीपेप्टिव मल्टीटास्किंग के बीच अंतर को समझता हूं। और मुझे उम्मीद थी कि इस मुद्दे के लिए यूवेस्गी धागे बेहतर होगा (नेटवर्क I/O बाधा)। लेकिन परिणाम लगभग समान थे। कभी-कभी gevent कमजोर था। शायद कहीं मैं गलत हूं। कृपया मुझे बताओ।गीवेन्ट बनाम धागे के साथ Uwsgi

यहां uwsgi कॉन्फ़िगरेशन उदाहरण हैं। Gevent:

$ uwsgi --http :8001 --module ugtest.wsgi --gevent 40 --gevent-monkey-patch 

थ्रेडिंग:

$ uwsgi --http :8001 --module ugtest.wsgi --enable-threads --threads 40 

नियंत्रक उदाहरण:

def simple_test_action(request): 
    # get data from API without parsing (only for simple I/O test) 
    data = _get_data_by_url(API_URL) 
    return JsonResponse(data, safe=False) 

import httplib 
from urlparse import urlparse 
def _get_data_by_url(url): 
    u = urlparse(url) 
    if str(u.scheme).strip().lower() == 'https': 
     conn = httplib.HTTPSConnection(u.netloc) 
    else: 
     conn = httplib.HTTPConnection(u.netloc) 
    path_with_params = '%s?%s' % (u.path, u.query,) 
    conn.request("GET", path_with_params) 
    resp = conn.getresponse() 
    print resp.status, resp.reason 
    body = resp.read() 
    return body 

टेस्ट (geventhttpclient के साथ):

def get_info(i): 
    url = URL('http://localhost:8001/simpletestaction/') 
    http = HTTPClient.from_url(url, concurrency=100, connection_timeout=60, network_timeout=60) 
    try: 
     response = http.get(url.request_uri) 
     s = response.status_code 
     body = response.read() 
    finally: 
     http.close() 


dt_start = dt.now() 
print 'Start: %s' % dt_start 

threads = [gevent.spawn(get_info, i) for i in xrange(401)] 
gevent.joinall(threads) 
dt_end = dt.now() 

print 'End: %s' % dt_end 
print dt_end-dt_start 

दोनों मामलों में मेरे पास एक समान समय है। एक समान मुद्दे (एपीआई प्रॉक्सीइंग) में एक gevent/greenlets और सहकारी मल्टीटास्किंग के फायदे क्या हैं?

उत्तर

5

40 की एक सहमति गुरुत्वाकर्षण चमकने के लिए ऐसा स्तर नहीं है। गेवेंट समरूपता (या प्रति-अनुरोध प्रदर्शन) नहीं समेकन के बारे में है, इसलिए समेकन का ऐसा "निम्न" स्तर होने से सुधार प्राप्त करने का एक अच्छा तरीका नहीं है।

आम तौर पर आप हजारों का एक स्तर के साथ gevent संगामिति देखेंगे, 40 :)

नहीं आई/ओ अजगर धागे अवरुद्ध के लिए बुरा नहीं कर रहे हैं (जीआईएल आई/ओ के दौरान जारी किया गया है), gevent का लाभ है संसाधन उपयोग में (1000 पायथन धागे अधिक हो जाएगा) और लॉकिंग और दोस्तों के बारे में सोचने की आवश्यकता को हटाने।

और जाहिर है, याद रखें कि आपका पूरा ऐप लाभ प्राप्त करने के लिए gevent- अनुकूल होना चाहिए, और django (डिफ़ॉल्ट रूप से) को थोड़ा ट्यूनिंग की आवश्यकता होती है (उदाहरण के लिए डेटाबेस एडाप्टर को कुछ gevent अनुकूल के साथ बदला जाना चाहिए)।

+0

मैं इसे अन्य धागे/ग्रीनलेट्स के साथ परीक्षण करने की कोशिश कर रहा हूं। हजारों नहीं, लेकिन सैकड़ों। और परिणाम समान है। मुझे लगता है कि अगर मेरे नियंत्रक कार्रवाई में एक से अधिक अनुरोध हैं (जॉइन()/joinall() का उपयोग कर, तो gevent सबसे अच्छा विकल्प है। लेकिन मेरे मुद्दे में ("प्रॉक्सी" -एपीआई) मेरे पास महत्वपूर्ण लाभ नहीं हैं। पहले मामले (धागे) में हमारे पास एक साधारण कॉन्फ़िगरेशन है: - थ्रेड एन दूसरे मामले में (गीवेंट) हमें पोस्टग्रेस ड्राइवर (उदाहरण के लिए), रेडिस इत्यादि पैचिंग के साथ बहुत सी समस्या है। इसके अलावा, हमारे पास है पूर्ण स्टैक ट्रेस के साथ एक समस्या ... – OLMER

+0

क्षमा करें, आप का पालन करना सुनिश्चित नहीं है, अगर आप django "पैच" नहीं कर सकते हैं, तो आप gevent का उपयोग नहीं कर सकते हैं। आपका ऐप 100% गैर-अवरुद्ध होना चाहिए, अन्यथा यह एक अवरुद्ध ऐप है और गीवेंट आपकी मदद नहीं करेगा (ठीक है, यह भी सबसे खराब होगा) – roberto

1

गैर-अवरुद्ध करने की सेवा प्रदर्शन के बारे में नहीं है, यह समरूपता के बारे में है। यदि 99% अनुरोध समय उप-अनुरोध में खर्च किया जाता है, तो आप केवल उन 99% को अनुकूलित नहीं कर सकते हैं। लेकिन जब सभी उपलब्ध धागे व्यस्त हो जाते हैं, तो नए ग्राहकों से इनकार कर दिया जाता है, हालांकि 99% थ्रेड का समय उप-अनुरोध पूरा होने की प्रतीक्षा में खर्च किया जाता है। गैर-अवरुद्ध करने से आप उस निष्क्रिय समय का उपयोग "हैंडलर" के बीच साझा करके कर सकते हैं जो उपलब्ध थ्रेड की संख्या से अधिक सीमित नहीं हैं। तो यदि 99% इंतजार कर रहा है, तो दूसरा 1% सीपीयू-बाध्य प्रसंस्करण है, इसलिए आप अपने सीपीयू को अधिकतम करने से पहले 100x अधिक कनेक्शन कर सकते हैं - बिना 100x अधिक धागे, जो कि बहुत महंगा हो सकता है (और पायथन के जीआईएल के साथ) मुद्दा, आपको उप-प्रक्रियाओं का उपयोग करना होगा जो कि अधिक महंगी हैं)।

अब रॉबर्टो ने कहा, आपका कोड निष्क्रिय समय बचाने के लिए 100% गैर-अवरोध होना चाहिए। हालांकि, जैसा कि आप ऊपर दिए गए प्रतिशत उदाहरण से देख सकते हैं, यह केवल तभी महत्वपूर्ण हो जाता है जब अनुरोध लगभग पूरी तरह से आईओ-बाउंड होते हैं।यदि ऐसा है, तो संभवतः आपको कम से कम अपने ऐप के उस हिस्से के लिए Django की आवश्यकता नहीं है।

संबंधित मुद्दे