2013-08-03 7 views
6

वहाँ कोड है,नोड.जेएस एसिंक समानांतर - क्या परिणाम हैं?

async.series(tasks, function (err) { 
    return callback ({message: 'tasks execution error', error: err}); 
}); 

जहां, tasks, इसके बारे में प्रत्येक HTTP अनुरोध (request मॉड्यूल का उपयोग करके) और डेटा (MongoHQ उदाहरण के लिए) स्टोर करने के लिए MongoDB एपीआई बुला peforms कार्यों की सरणी है।

मेरे वर्तमान इनपुट के साथ

, (~ 200 कार्य निष्पादित करने के लिए), यह

[normal mode] collection cycle: 1356.843 sec. (22.61405 mins.) 

लेता है लेकिन बस series से parallel करने के लिए परिवर्तन की कोशिश कर रहा है, यह शानदार लाभ देता है। कार्यों में से लगभग एक ही राशि ~30 secs बजाय ~23 mins में चलाते हैं।

लेकिन, यह जानकर कुछ भी नहीं मुक्त करने के लिए है कि, मैं क्या है कि परिवर्तन के परिणामों को समझने की कोशिश कर रहा हूँ? क्या मैं बता सकता हूं कि खुले सॉकेट की संख्या बहुत अधिक होगी, अधिक स्मृति खपत, डीबी सर्वर पर अधिक हिट होगी?

मशीन है कि मैं कोड चलाने रैम Ubuntu के केवल 1GB है, इसलिए मैं इतना है कि एप्लिकेशन वहाँ एक बार लटका हुआ है, यह संसाधनों की कमी की वजह से हो सकता है?

+1

आपको शायद बेहतर प्रदर्शन के लिए 'async.parallelLimit (सरणी, सीमा, सीबी)' का उपयोग करना चाहिए और उपयोग करना चाहिए। समानांतर निष्पादन की एक सीमा पाएं जो निष्पादन को ओवरफ़्लो नहीं करती है, और यह async.parallel से तेज होगी: पी बोनस के रूप में, यह अब और नहीं लटका होगा :) – randunel

उत्तर

5

अपने अंतर्ज्ञान सही है कि समानांतरवाद मुक्त करने के लिए नहीं आता है, लेकिन आप निश्चित रूप से इसके लिए भुगतान करने में सक्षम हो सकता है।

nodeload जैसे लोड परीक्षण मॉड्यूल (या मॉड्यूल का संग्रह) का उपयोग करके, आप यह निर्धारित कर सकते हैं कि यह समांतर ऑपरेशन यह निर्धारित करने के लिए आपके सर्वर को कैसे प्रभावित कर रहा है कि यह स्वीकार्य है या नहीं।

Async.parallelLimit यदि आपको आवश्यकता हो तो सर्वर लोड को सीमित करने का एक अच्छा तरीका हो सकता है, लेकिन पहले यह महत्वपूर्ण है कि सीमित होना आवश्यक है। स्पष्ट रूप से परीक्षण करना आपके सिस्टम की सीमाओं को खोजने का सबसे अच्छा तरीका है (प्रत्येक लिमिट के पास एक अलग हस्ताक्षर है, लेकिन इसका भी उपयोग किया जा सकता है)।

इसके अलावा, async.parallel का उपयोग करने वाले सामान्य नुकसान में उस फ़ंक्शन ऑफ़र (जो, आपके विवरण से लागू नहीं होता है) से अधिक जटिल नियंत्रण प्रवाह चाहते हैं और संग्रह के बहुत बड़े संग्रह पर समानांतर का उपयोग करना (जो, कहें , यदि आप कई फाइलें लिख रहे हैं तो आप अपने सिस्टम की फाइल डिस्क्रिप्टर सीमा में टक्कर ले सकते हैं)। अपने ~ 200 अनुरोध और 1GB RAM पर कार्रवाई को बचाने के साथ, मैं कल्पना कर सकते हैं आप जब तक ठीक होगा के रूप में आप ईवेंट हैंडलर्स में ज्यादा मालिश कर रही है नहीं कर रहे हैं, लेकिन अगर आप सर्वर रुक जाता है का सामना कर रहे, parallelLimit एक अच्छा तरीका है बाहर हो सकता है।

फिर, परीक्षण सबसे अच्छा तरीका है इन बातों को यह पता लगाने की है।

+0

मैं 24-30 घंटे के आवेदन के बाद सर्वर को लटका अनुभव करता हूं (सीरियल निष्पादन के साथ भी), ऐप को पुनरारंभ करने के लिए अब केवल एक वर्कअराउंड है। मैं घायल हूं कि स्मृति या कुछ से बाहर होने के कारण (कोई त्रुटि नहीं है, लेकिन http अनुरोध सिर्फ लटकता है) .. –

+0

यह एक ओवरलोडेड सर्वर से अधिक मेमोरी लीक की तरह लगता है। आप 24-30 घंटे की अवधि के दौरान 200 कार्य चक्र कितनी बार चल रहे हैं? – Wyatt

+0

अक्सर, 100 बार तक ..मुझे स्मृति रिसाव पर भी संदेह है, लेकिन इससे निपटना मुश्किल है। –

0

मुख्य नकारात्मक पक्ष यह है कि आप देखेंगे डेटाबेस सर्वर लोड में एक कील है। यह आपके सेटअप के आधार पर ठीक हो सकता है या नहीं भी हो सकता है।

अपने डेटाबेस सर्वर एक साझा संसाधन है तो आप शायद बजाय async.eachLimit का उपयोग करके समानांतर अनुरोधों को सीमित करना चाहते होंगे।

3

मैं कहना है कि async.parallel अनेक कार्यों का कार्यान्वित समवर्ती नहीं (पूरी तरह से) parallely। यह वर्चुअल समांतरता की तरह है।

समवर्ती निष्पादित एक भी सीपीयू कोर पर विभिन्न कार्यक्रमों को चलाने, मल्टीटास्किंग/शेड्यूलिंग के माध्यम से की तरह है। यह सच है समानांतर निष्पादन मल्टी कोर CPU के प्रत्येक कोर पर विभिन्न कार्यक्रम चलाने होगा। इस नोड के रूप में महत्वपूर्ण है।जेएस सिंगल थ्रेडेड आर्किटेक्चर है।

नोड के बारे में सबसे अच्छी बात यह है कि आपको I/O के बारे में चिंता करने की आवश्यकता नहीं है। यह I/O बहुत कुशलता से संभालता है।

आपके मामले में आप MongoDB को डेटा संग्रहीत कर रहे हैं, ज्यादातर I/O है। तो उन्हें समानांतर चलाना आपके नेटवर्क बैंडविड्थ का उपयोग करेगा और डिस्क से पढ़ने/लिखने पर डिस्क बैंडविड्थ भी होगा। आपका सर्वर CPU अधिभार के कारण लटका नहीं होगा।


इसका परिणाम यह होगा कि यदि आप अपने सर्वर को ओवरबर्ड करते हैं, तो आपके अनुरोध विफल हो सकते हैं। आपको EMFILE त्रुटि मिल सकती है (बहुत सारी खुली फ़ाइलें)। प्रत्येक सॉकेट फ़ाइल के रूप में गिना जाता है। आम तौर पर कनेक्शन पूल किए जाते हैं, जिसका मतलब है कि कनेक्शन स्थापित करना पूल से सॉकेट उठाया जाता है और जब पूल में वापस आ जाता है। आप ulimit -n xxxx के साथ फ़ाइल डिस्क्रिप्टर को बढ़ा सकते हैं।

ECONNRESET (त्रुटि: सॉकेट लटका हुआ), ECONNREFUSED या ETIMEDOUT जैसे अतिरंजित होने पर आपको सॉकेट त्रुटियां भी मिल सकती हैं। तो उन्हें ठीक से संभाल लें। मोंगो डीबी सर्वर के लिए भी एक साथ कनेक्शन की अधिकतम संख्या की जांच करें।


अंत में सर्वर कचरा संग्रह के कारण लटक सकता है। आपकी याददाश्त एक निश्चित बिंदु तक बढ़ने के बाद कचरा संग्रह में आता है, फिर कुछ समय बाद समय-समय पर चलता है। अधिकतम ढेर मेमोरी वी 8 के पास लगभग 1.5 जीबी हो सकती है, इसलिए इसकी याददाश्त उच्च होने पर जीसी को अक्सर चलाने की उम्मीद है। उस सीमा से अधिक पूछने पर नोड process out of memory के साथ दुर्घटनाग्रस्त हो जाएगा। तो अपने कार्यक्रम में मेमोरी लीक को ठीक करें। आप इन tools देख सकते हैं।

0

यदि एक से अधिक उपयोगकर्ताओं को कनेक्ट आप अंतर का एहसास होगा:

इस मामले में प्रोसेसर कई आपरेशनों

asynch रिश्तेदार एकाधिक उपयोगकर्ताओं के कई आपरेशनों को चलाने के लिए कोशिश करता है संभाल कर सकते हैं बराबर

T = task 
U = user 
(T1.U1 = task 1 of user 1) 

T1.U1 => T1.U2 => T2.U1 => T8.U3 => T2.U2 => etc 

यह परमाणु का oposite है (तो शायद विशेष डीबी संचालन पर परमाणु के लिए देखो - लेकिन यह एक और विषय है)

तो मी aybe इसका इस्तेमाल करने के तेजी से होता है:

T2.U1 before T1.U1 

- यह जब तक

T2.U1 is based on T1.U1 

कोई समस्या नहीं है - यह कॉलबैक का उपयोग करके रोका जा सकता है/या इसलिए कॉलबैक

रहे हैं ... उम्मीद है कि यह क्या है आप जानना चाहते थे ... यह थोड़ा देर हो चुकी है

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