javascript - बहु-कोर मशीनों पर Node.js




node-cluster (9)

[ यह पोस्ट 2012-09-02 (ऊपर से ऊपर) के रूप में अद्यतित है। ]

Node.js बिल्कुल बहु-कोर मशीनों पर स्केल करता है।

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

तो मैं अपने 16 कोर बॉक्स का लाभ कैसे ले सकता हूं?

दो तरीके:

  • छवि एन्कोडिंग जैसे बड़े भारी गणना कार्यों के लिए, नोड.जेएस बाल प्रक्रियाओं को आग लग सकता है या अतिरिक्त कार्यकर्ता प्रक्रियाओं को संदेश भेज सकता है। इस डिज़ाइन में, आपके पास एक थ्रेड होगा जो घटनाओं के प्रवाह का प्रबंधन करेगा और एन प्रक्रियाएं भारी गणना कार्य कर रही हैं और अन्य 15 सीपीयू चबाने वाली हैं।
  • किसी webservice पर थ्रूपुट स्केल करने के लिए, आपको एक बॉक्स पर एकाधिक Node.js सर्वर चलाएंगे, एक प्रति कोर और उनके बीच विभाजित अनुरोध ट्रैफ़िक। यह उत्कृष्ट सीपीयू-एफ़िनिटी प्रदान करता है और कोर गिनती के साथ लगभग रैखिक रूप से स्केल करेगा।

एक webservice पर थ्रूपुट स्केलिंग

चूंकि v6.0.X Node.js ने क्लस्टर मॉड्यूल को सीधे बॉक्स के बाहर शामिल किया है , जिससे एकल नोड श्रमिकों को स्थापित करना आसान हो जाता है जो एकल पोर्ट पर सुन सकते हैं। ध्यान दें कि यह npm माध्यम से पुराना सीखने वाला "क्लस्टर" मॉड्यूल जैसा नहीं है।

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  http.Server(function(req, res) { ... }).listen(8000);
}

श्रमिक नए कनेक्शन स्वीकार करने के लिए प्रतिस्पर्धा करेंगे, और कम से कम लोड की गई प्रक्रिया जीतने की संभावना है। यह बहुत अच्छी तरह से काम करता है और बहु-कोर बॉक्स पर काफी अच्छी तरह से थ्रूपुट स्केल कर सकता है।

यदि आपके पास एकाधिक कोर के बारे में परवाह करने के लिए पर्याप्त भार है, तो आप कुछ और चीजें भी करना चाहेंगे:

  1. Nginx या Apache जैसे वेब-प्रॉक्सी के पीछे अपनी नोड.जेएस सेवा चलाएं - कुछ ऐसा जो कनेक्शन थ्रॉटलिंग कर सकता है (जब तक आप बॉक्स को पूरी तरह से नीचे लाने के लिए ओवरलोड शर्तों को नहीं चाहते हैं), यूआरएल को फिर से लिखें, स्थिर सामग्री की सेवा करें, और अन्य उप-सेवाओं प्रॉक्सी करें।

  2. समय-समय पर अपनी कार्यकर्ता प्रक्रियाओं को रीसायकल करें। एक लंबी चल रही प्रक्रिया के लिए, अंततः एक छोटी स्मृति रिसाव भी जोड़ देगा।

  3. सेटअप लॉग संग्रह / निगरानी

पीएस: एक और पोस्ट की टिप्पणियों में हारून और क्रिस्टोफर के बीच एक चर्चा है (इस लेखन के रूप में, इसकी शीर्ष पोस्ट)। उस पर कुछ टिप्पणियां:

  • एक साझा सॉकेट मॉडल एक ही बंदरगाह पर कई प्रक्रियाओं को सुनने की अनुमति देने के लिए बहुत सुविधाजनक है और नए कनेक्शन स्वीकार करने के लिए प्रतिस्पर्धा करता है। संकल्पनात्मक रूप से, आप पूर्ववर्ती अपाचे के बारे में सोच सकते हैं कि यह महत्वपूर्ण चेतावनी के साथ ऐसा कर रहा है कि प्रत्येक प्रक्रिया केवल एक कनेक्शन स्वीकार करेगी और फिर मर जाएगी। अपाचे के लिए दक्षता हानि नई प्रक्रियाओं को तोड़ने के ऊपरी हिस्से में है और सॉकेट परिचालनों से कोई लेना देना नहीं है।
  • Node.js के लिए, एन श्रमिकों को एक सॉकेट पर प्रतिस्पर्धा करना बेहद उचित समाधान है। विकल्प Nginx की तरह एक ऑन-बॉक्स फ्रंट-एंड सेट करना है और नए कर्मचारियों को असाइन करने के लिए श्रमिकों के बीच वैकल्पिक, व्यक्तिगत श्रमिकों के लिए वह प्रॉक्सी ट्रैफिक है। दो समाधानों में बहुत ही समान प्रदर्शन विशेषताएं हैं। और चूंकि, जैसा कि मैंने उपर्युक्त उल्लेख किया है, आप शायद अपने नोड सेवा को आगे बढ़ने के लिए निगेंक्स (या वैकल्पिक) चाहते हैं, यहां पर विकल्प वास्तव में है:

साझा पोर्ट्स: nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)

बनाम

व्यक्तिगत बंदरगाह: nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}

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

Node.js दिलचस्प लग रहा है, लेकिन मुझे कुछ याद करना चाहिए - नोड.जेएस केवल एक ही प्रक्रिया और धागे पर चलाने के लिए ट्यून नहीं किया गया है?

फिर यह बहु-कोर CPUs और बहु-CPU सर्वर के लिए कैसे स्केल करता है? आखिरकार, संभवतः एकल-थ्रेड सर्वर जितना तेज़ बनाना बहुत अच्छा है, लेकिन उच्च भार के लिए मैं कई CPUs का उपयोग करना चाहता हूं। और यह अनुप्रयोगों को तेजी से बनाने के लिए भी जाता है - ऐसा लगता है कि आज कई CPUs का उपयोग किया जाता है और कार्यों को समानांतर करता है।

Node.js इस तस्वीर में कैसे फिट है? क्या इसका विचार किसी भी तरह से कई उदाहरणों को वितरित करना है या क्या?


आप क्लस्टर मॉड्यूल का उपयोग कर सकते हैं। इसे जांचें

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    // Fork workers.
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', function(worker, code, signal) {
        console.log('worker ' + worker.process.pid + ' died');
    });
} else {
    // Workers can share any TCP connection
    // In this case its a HTTP server
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    }).listen(8000);
}

जैसा ऊपर बताया गया है, Cluster आपके ऐप को सभी कोरों में स्केल और लोड-बैलेंस करेगा।

कुछ जोड़ना

cluster.on('exit', function () {
  cluster.fork();
});

किसी भी असफल श्रमिकों को पुनरारंभ करेगा।

इन दिनों, बहुत से लोग github.com/Unitech/pm2 पसंद करते हैं, जो आपके लिए क्लस्टरिंग को संभालता है और कुछ शांत निगरानी सुविधाएं भी प्रदान करता है

फिर, क्लस्टरिंग के साथ चल रही कई मशीनों के सामने Nginx या HAProxy जोड़ें और आपके पास कई स्तरों के फेलओवर और बहुत अधिक लोड क्षमता है।


नोड का भविष्य संस्करण आपको एक प्रक्रिया को फोर्क करने और संदेशों को पास करने की अनुमति देगा और रयान ने कहा है कि वह फ़ाइल हैंडलर साझा करने के लिए कुछ रास्ता ढूंढना चाहता है, इसलिए यह सीधे वेब वर्कर कार्यान्वयन नहीं होगा।

इस समय इसके लिए कोई आसान समाधान नहीं है लेकिन यह अभी भी बहुत शुरुआती है और नोड सबसे तेज़ी से चलने वाली ओपन सोर्स प्रोजेक्ट्स में से एक है जिसे मैंने कभी देखा है ताकि निकट भविष्य में कुछ शानदार हो।


प्रत्येक नोडजेएस प्रक्रिया को चलाने वाले कई बक्से के सामने शुद्ध टीसीपी लोड बैलेंसर (हैप्रोक्सी) का उपयोग करके कई बॉक्स में नोडजेएस को स्केल करना संभव है।

यदि आपके पास सभी उदाहरणों के बीच साझा करने के लिए कुछ सामान्य ज्ञान है तो आप केंद्रीय रेडिस स्टोर या इसी तरह का उपयोग कर सकते हैं जिसे तब सभी प्रक्रिया उदाहरणों से उपयोग किया जा सकता है (उदाहरण के लिए सभी बक्से से)


मल्टी-नोड आपके पास मौजूद सभी कोरों का उपयोग करता है।
http://github.com/kriszyp/multi-node पर एक नज़र डालें।

सरल जरूरतों के लिए, आप विभिन्न पोर्ट नंबरों पर नोड की कई प्रतियां शुरू कर सकते हैं और उनके सामने लोड बैलेंसर डाल सकते हैं।


यहां ब्लॉक पर नया बच्चा LearnBoost की "Up"

यह "ज़ीरो-डाउनटाइम रीलोड्स" प्रदान करता है और इसके अतिरिक्त कई श्रमिकों को प्रदान करता है (डिफ़ॉल्ट रूप से सीपीयू की संख्या, लेकिन यह कॉन्फ़िगर करने योग्य है) सभी दुनिया के सर्वश्रेष्ठ प्रदान करने के लिए।

यह नया है, लेकिन यह बहुत स्थिर प्रतीत होता है, और मैं अपनी वर्तमान परियोजनाओं में से एक में खुशी से इसका उपयोग कर रहा हूं।


रयान डाहल ने पिछले गर्मियों में Google में दिए गए तकनीकी वार्ता में इस प्रश्न का उत्तर दिया । पैराफ्रेश करने के लिए, "बस कई नोड प्रक्रियाएं चलाएं और उन्हें संचार करने की अनुमति देने के लिए कुछ समझदार उपयोग करें। उदाहरण के लिए sendmsg () - शैली आईपीसी या पारंपरिक आरपीसी"।

अगर आप तुरंत अपने हाथ गंदे करना चाहते हैं, तो spark2 Forever मॉड्यूल देखें। यह कई नोड प्रक्रियाओं को आसानी से आसान बनाता है। यह बंदरगाह साझा करने की स्थापना को संभालता है, ताकि वे प्रत्येक एक ही बंदरगाह से कनेक्शन स्वीकार कर सकें, और यदि आप यह सुनिश्चित करना चाहते हैं कि कोई प्रक्रिया फिर से शुरू हो जाए तो यह प्रक्रिया फिर से शुरू हो जाती है।

अद्यतन - 10/11/11 : नोड समुदाय में आम सहमति यह प्रतीत होती है कि Cluster अब प्रति मशीन एकाधिक नोड इंस्टेंस प्रबंधित करने के लिए पसंदीदा मॉड्यूल है। Forever एक लायक भी लायक है।


स्पार्क 2 स्पार्क पर आधारित है जिसे अब बनाए रखा नहीं गया है। Cluster इसके उत्तराधिकारी हैं, और इसमें कुछ शानदार विशेषताएं हैं, जैसे प्रति सीपीयू कोर में एक कार्यकर्ता प्रक्रिया को बढ़ावा देना और मृत श्रमिकों को राहत देना।





node-cluster