Node.js और CPU गहन अनुरोध


215

मैंने Node.js HTTP सर्वर के साथ छेड़छाड़ शुरू कर दी है और वास्तव में सर्वर साइड जावास्क्रिप्ट लिखना पसंद करता हूं, लेकिन कुछ मुझे अपने वेब एप्लिकेशन के लिए Node.js का उपयोग करना शुरू करने से रोक रहा है।

मैं संपूर्ण async I / O कॉन्सेप्ट को समझता हूं, लेकिन मैं उन एज मामलों के बारे में कुछ चिंतित हूं जहां प्रक्रियात्मक कोड बहुत सीपीयू गहन है जैसे कि छवि हेरफेर या बड़े डेटा सेट को सॉर्ट करना।

जैसा कि मैं इसे समझता हूं, सरल वेब पेज अनुरोधों के लिए सर्वर बहुत तेज़ होगा जैसे कि उपयोगकर्ताओं की सूची देखना या ब्लॉग पोस्ट देखना। हालाँकि, यदि मैं बहुत सीपीयू सघन कोड लिखना चाहता हूं (उदाहरण के लिए एडमिन बैक एंड में) जो ग्राफिक्स उत्पन्न करता है या हजारों छवियों का आकार बदलता है, तो अनुरोध बहुत धीमा (कुछ सेकंड) होगा। चूँकि यह कोड async नहीं है, इसलिए सर्वर पर आने वाले प्रत्येक अनुरोध को कुछ सेकंड के दौरान अवरुद्ध कर दिया जाएगा जब तक कि मेरा धीमा अनुरोध नहीं किया जाता है।

एक सुझाव सीपीयू गहन कार्यों के लिए वेब वर्कर्स का उपयोग करना था। हालाँकि, मुझे डर है कि वेब कर्मचारी एक अलग जेएस फ़ाइल को शामिल करके काम करने के बाद से स्वच्छ कोड लिखना मुश्किल बना देंगे। क्या होगा यदि सीपीयू गहन कोड किसी वस्तु की विधि में स्थित हो? यह सीपीयू गहन है कि हर विधि के लिए एक जेएस फ़ाइल लिखने के लिए बेकार है।

एक अन्य सुझाव था कि एक बच्चे की प्रक्रिया को बढ़ावा दिया जाए, लेकिन यह कोड को और भी कम बनाए रखता है।

इस (कथित) बाधा को दूर करने के लिए कोई सुझाव? सीपीयू भारी कार्यों को एसिंक्स निष्पादित करते समय सुनिश्चित करें कि आप Node.js के साथ स्वच्छ वस्तु उन्मुख कोड कैसे लिखते हैं?


2
ओलिवियर, आपने उसी तरह का प्रश्न पूछा जो मेरे मन में था (नया नोड) और विशेष रूप से प्रसंस्करण छवियों के संबंध में। जावा में, मैं एक निश्चित-थ्रेड एक्सेकॉर्स सर्विस का उपयोग कर सकता हूं और इसे सभी रिसाइज़ नौकरियों को पास कर सकता हूं और सभी कनेक्शन से समाप्त होने के लिए इंतजार कर सकता हूं, नोड में, मुझे यह पता नहीं चला है कि बाहरी मॉड्यूल पर काम को कैसे फेरबदल करना है (सीमाएं कहते हैं) एक समय में एक साथ संचालन की अधिकतम संख्या 2 है। क्या आपको ऐसा करने का एक सुंदर तरीका मिला?
रियाद कल्ला

जवाबों:


55

क्या आप की जरूरत है एक काम कतार है! अपने लंबे चलने वाले कार्यों को वेब-सर्वर से बाहर ले जाना एक अच्छी बात है। प्रत्येक कार्य को "अलग" जेएस फ़ाइल में रखने से प्रतिरूपकता और कोड पुन: उपयोग को बढ़ावा मिलता है। यह आपको यह सोचने के लिए मजबूर करता है कि अपने कार्यक्रम को इस तरह से कैसे तैयार किया जाए कि यह लंबे समय तक डिबग करना और बनाए रखना आसान हो जाए। कार्य कतार का एक और लाभ यह है कि श्रमिकों को एक अलग भाषा में लिखा जा सकता है। बस एक कार्य पॉप, काम करते हैं, और प्रतिक्रिया वापस लिखें।

कुछ इस तरह https://github.com/resque/resque

यहाँ github का एक लेख है कि उन्होंने इसे क्यों बनाया है http://github.com/blog/542-introducing-ceque


35
आप रूबी पुस्तकालयों को विशेष रूप से नोड दुनिया में एक प्रश्न में क्यों जोड़ रहे हैं?
जोनाथन ड्यूमाइन

1
@JonathanDumaine यह एक कार्य कतार का अच्छा कार्यान्वयन है। माणिक कोड को रेड करें और इसे जावास्क्रिप्ट में फिर से लिखें। फायदा!
साइमन स्टेंडर बोइसन

2
मैं इसके लिए गियरमैन का बहुत बड़ा प्रशंसक हूं, गियरमैन श्रमिक नई नौकरियों के लिए गियरमैन सर्वर का चुनाव नहीं करते हैं - नई नौकरियों को तुरंत श्रमिकों के लिए धकेल दिया जाता है। बहुत ही संवेदनशील
केसी फ्लिन

1
वास्तव में, किसी ने इसे नोड दुनिया में चित्रित किया है
FrontierPsycho

@ स्पेसर, आप ऐसा क्यों कहते हैं? आपका क्या सुझाव है?
luis.espinal

289

यह वेब सर्वर की परिभाषा की गलतफहमी है - इसका उपयोग केवल ग्राहकों के साथ "बात" करने के लिए किया जाना चाहिए। भारी भार कार्यों को स्टैंडअलोन कार्यक्रमों के लिए निर्दिष्ट किया जाना चाहिए (जो कि JS में भी लिखा जा सकता है)।
आप शायद कहेंगे कि यह गंदा है, लेकिन मैं आपको विश्वास दिलाता हूं कि छवियों को आकार देने में फंसी एक वेब सर्वर प्रक्रिया सिर्फ बदतर है (यहां तक ​​कि अपाचे को कहने की अनुमति नहीं है, जब यह अन्य प्रश्नों को ब्लॉक नहीं करता है)। फिर भी, आप कोड अतिरेक से बचने के लिए एक सामान्य पुस्तकालय का उपयोग कर सकते हैं।

संपादित करें: मैं एक सादृश्य के साथ आया हूं; वेब अनुप्रयोग एक रेस्तरां के रूप में होना चाहिए। आपके पास वेटर (वेब ​​सर्वर) और कुक (कार्यकर्ता) हैं। वेटर ग्राहकों के संपर्क में हैं और सरल कार्य करते हैं जैसे मेनू प्रदान करना या यह समझाना कि कुछ पकवान शाकाहारी है। दूसरी ओर वे रसोई में कठिन कार्य सौंपते हैं। क्योंकि वेटर केवल साधारण चीजें कर रहे हैं जो वे त्वरित प्रतिक्रिया देते हैं, और रसोइये अपनी नौकरी पर ध्यान केंद्रित कर सकते हैं।

यहाँ Node.js एक एकल लेकिन बहुत प्रतिभाशाली वेटर होगा जो एक समय में कई अनुरोधों को संसाधित कर सकता है, और अपाचे गूंगा वेटर का एक गिरोह होगा जो सिर्फ एक अनुरोध को संसाधित करता है। यदि यह एक Node.js वेटर खाना बनाना शुरू कर देगा, तो यह एक तत्काल तबाही होगी। फिर भी, खाना पकाने के लिए अपाचे वेटरों की एक बड़ी आपूर्ति भी समाप्त हो सकती है, रसोई में अव्यवस्था का उल्लेख नहीं करना और जिम्मेदारी की प्रगतिशील कमी।


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

13
हर अनुरोध के लिए एक बच्चे की प्रक्रिया न करें (जो कि नोड के उद्देश्य को पराजित करता है)। केवल अपने भारी अनुरोधों के अंदर से स्पॉन कार्यकर्ता। या नोड के अलावा किसी अन्य चीज़ के लिए अपनी भारी पृष्ठभूमि का काम करें।
थिलो

47
अच्छा सादृश्य, mbq!
लांस फिशर

6
हा, मुझे वास्तव में यह पसंद है। "Node.js: बुरा व्यवहार करना बुरी तरह से काम करता है"
एथन

7
@mbq मुझे सादृश्य पसंद है लेकिन यह कुछ काम का उपयोग कर सकता है। पारंपरिक बहुआयामी मॉडल एक ऐसा व्यक्ति होगा जो वेटर और कुक दोनों है। एक बार ऑर्डर लेने के बाद, उस व्यक्ति को वापस जाना होगा और दूसरे ऑर्डर को संभालने में सक्षम होने से पहले भोजन पकाना होगा। नोड.जेएस मॉडल में वेटर के रूप में नोड्स और कुक के रूप में वेबवर्क हैं। वेटर अनुरोधों को प्राप्त / हल करने का काम संभालते हैं, जबकि कार्यकर्ता अधिक समय-गहन कार्यों का प्रबंधन करते हैं। यदि आपको बड़े पैमाने पर करने की आवश्यकता है तो आप मुख्य सर्वर को नोड क्लस्टर बनाते हैं और सीपीयू के गहन कार्यों को अन्य थ्रेडों को रिवर्स करते हैं जो कि मिलिट्री-थ्रेड प्रोसेसिंग के लिए बनाया गया है।
इवान प्लाइस

16

आप अपने CPU गहन कोड को एसिंक्स को निष्पादित नहीं करना चाहते हैं, आप चाहते हैं कि यह समानांतर में निष्पादित हो । आपको HTTP अनुरोधों की सेवा करने वाले थ्रेड से प्रसंस्करण कार्य प्राप्त करने की आवश्यकता है। यह इस समस्या को हल करने का एकमात्र तरीका है। NodeJS के साथ उत्तर क्लस्टर मॉड्यूल है, बच्चों की प्रक्रिया के लिए भारी उठाने के लिए। (AFAIK नोड में थ्रेड्स / शेयर्ड मेमोरी की कोई अवधारणा नहीं है; यह प्रक्रिया है या कुछ भी नहीं है)। आपके पास दो विकल्प हैं कि आप अपने आवेदन को किस तरह से तैयार करते हैं। आप 8 HTTP सर्वरों को पैदा करके और बाल प्रक्रियाओं पर तुल्यकालिक कार्यों की गणना करके 80/20 समाधान प्राप्त कर सकते हैं। ऐसा करना काफी सरल है। आपको उस लिंक पर इसके बारे में पढ़ने में एक घंटा लग सकता है। वास्तव में, यदि आप उस लिंक के शीर्ष पर उदाहरण कोड को चीर देते हैं, तो आप अपने आप को वहां के रास्ते का 95% प्राप्त कर लेंगे।

इसकी संरचना करने का दूसरा तरीका है, नौकरी की कतार लगाना और कतार के ऊपर बड़े गणना कार्यों को भेजना। ध्यान दें कि नौकरी की कतार के लिए आईपीसी के साथ बहुत अधिक ओवरहेड जुड़ा हुआ है, इसलिए यह केवल तभी उपयोगी है जब कार्य ओवरहेड की तुलना में प्रशंसनीय रूप से बड़ा हो।

मुझे आश्चर्य है कि इनमें से कोई भी उत्तर क्लस्टर का उल्लेख नहीं करता है।

पृष्ठभूमि: अतुल्यकालिक कोड वह कोड है जो तब तक निलंबित रहता है जब तक कि कहीं और कुछ नहीं होता है , जिस बिंदु पर कोड उठता है और निष्पादन जारी रखता है। एक बहुत ही सामान्य मामला जहां कुछ धीमा होना चाहिए कहीं और I / O है।

एसिंक्रोनस कोड उपयोगी नहीं है यदि यह आपका प्रोसेसर है जो काम करने के लिए जिम्मेदार है। यही कारण है कि "गणना गहन" कार्यों के साथ मामला है।

अब, ऐसा लग सकता है कि एसिंक्रोनस कोड आला है, लेकिन वास्तव में यह बहुत आम है। यह सिर्फ गहन कार्यों की गणना के लिए उपयोगी नहीं होता है।

I / O पर प्रतीक्षा करना एक पैटर्न है जो हमेशा वेब सर्वर में होता है, उदाहरण के लिए। हर ग्राहक जो आपके से जुड़ता है उसे सॉकेट मिलता है। ज्यादातर समय कुर्सियां ​​खाली रहती हैं। जब तक एक सॉकेट कुछ डेटा प्राप्त नहीं करता है, तब तक आप कुछ भी नहीं करना चाहते हैं, जिस बिंदु पर आप अनुरोध को संभालना चाहते हैं। हुड के तहत एनओडी जैसे HTTP सर्वर हजारों ओपन सॉकेट्स का ट्रैक रखने के लिए एक इवेंटिंग लाइब्रेरी (लिबेव) का उपयोग कर रहा है। ओएस कामवासना को सूचित करता है, और तब कामदेव NodeJS को सूचित करता है, जब सॉकेट्स में से एक को डेटा मिलता है, और फिर NodeJS इवेंट कतार में एक घटना डालता है, और आपका http कोड इस बिंदु पर किक करता है और एक के बाद एक घटनाओं को संभालता है। जब तक सॉकेट में कुछ डेटा नहीं होता है, तब तक इवेंट कतार में नहीं आते हैं, इसलिए इवेंट डेटा पर कभी भी इंतजार नहीं कर रहे हैं - यह उनके लिए पहले से ही है।

एकल थ्रेडेड ईवेंट-आधारित वेब सर्वर एक प्रतिमान के रूप में समझ में आता है जब अड़चन ज्यादातर खाली सॉकेट कनेक्शनों के एक समूह पर प्रतीक्षा कर रही है और आप हर निष्क्रिय कनेक्शन के लिए एक संपूर्ण थ्रेड या प्रक्रिया नहीं चाहते हैं और आप अपना 250k सर्वेक्षण नहीं करना चाहते हैं उस पर डेटा को खोजने के लिए सॉकेट।


सही उत्तर होना चाहिए .... समाधान के लिए जहां आप 8 क्लस्टर बनाते हैं, आपको 8 कोर की आवश्यकता होगी? या कई सर्वरों के साथ बैलेंसर लोड करें।
मुहम्मद उमर

यह भी 2 पंक्ति समाधान के बारे में जानने का एक अच्छा तरीका है, एक कतार की स्थापना। कतार की अवधारणा बहुत सरल है, लेकिन यह प्रक्रियाओं और कतार के बीच का संदेश है जो विदेशी है।
मुहम्मद उमर

ये सही है। आपको किसी अन्य तरह से काम करने की आवश्यकता है। उसके लिए, आपको एक और कोर की आवश्यकता है।
मस्कॉन्क

पुन: कतारें। व्यावहारिक उत्तर नौकरी की कतार का उपयोग करना है। नोड के लिए कुछ उपलब्ध हैं। मैंने उनमें से किसी का भी उपयोग नहीं किया है इसलिए मैं सिफारिश नहीं कर सकता। जिज्ञासा का उत्तर यह है कि कार्यकर्ता प्रक्रियाएं और कतार प्रक्रियाएं अंततः सॉकेट पर संवाद करने जा रही हैं।
मासक

7

दृष्टिकोण के जोड़े आप उपयोग कर सकते हैं।

@Tim नोट्स के रूप में, आप एक अतुल्यकालिक कार्य बना सकते हैं जो आपके मुख्य सेवारत तर्क के बाहर या समानांतर बैठता है। आपकी सटीक आवश्यकताओं पर निर्भर करता है, लेकिन यहां तक ​​कि क्रोन एक कतारबद्ध तंत्र के रूप में कार्य कर सकता है।

WebWorkers आपके async प्रक्रियाओं के लिए काम कर सकते हैं लेकिन वे वर्तमान में node.js. द्वारा समर्थित नहीं हैं ऐसे कुछ एक्सटेंशन हैं जो सहायता प्रदान करते हैं, उदाहरण के लिए: http://github.com/cramforce/node-worker

आप अभी भी प्राप्त करते हैं आप अभी भी मॉड्यूल का पुन: उपयोग कर सकते हैं और मानक "आवश्यकता" तंत्र के माध्यम से कोड कर सकते हैं। आपको केवल यह सुनिश्चित करने की आवश्यकता है कि कार्यकर्ता को प्रारंभिक प्रेषण परिणामों को संसाधित करने के लिए आवश्यक सभी जानकारी पास करता है।


0

उपयोग child_processएक उपाय है। लेकिन प्रत्येक बच्चे के जन्म की प्रक्रिया गो की तुलना में बहुत अधिक मेमोरी का उपभोग कर सकती हैgoroutines

तुम भी क्यू के रूप में कतार आधारित समाधान का उपयोग कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.