2011-03-13 10 views
28

में मानक धागे, थ्रेडपूल और टीपीएल का उपयोग कब करें, मैं हाल ही में थ्रेडिंग के बारे में बहुत कुछ पढ़ रहा हूं क्योंकि मैं उच्च प्रदर्शन, स्केलेबल टीसीपी सर्वर को संभालने में सक्षम हूं 10,000-20,000 ग्राहक, जिनमें से प्रत्येक ग्राहक लगातार कमांड-आधारित सिस्टम के साथ सर्वर पर द्विपक्षीय रूप से संचार कर रहा है। सर्वर को कमांड प्राप्त होगा, और आदेश के अनुसार या तो एकल (या कई) कार्य निष्पादित करेगा। मेरा सवाल यह है कि काम करने के आधार पर विभिन्न स्थितियों के लिए .NET थ्रेडिंग संरचनाओं का उचित उपयोग कैसे करें, कार्यों को निष्पादित करना जो एक मिनट से कई घंटों तक ले सकता है।सी # - एक उच्च गतिविधि सर्वर

मुझे सबसे ज्यादा भ्रमित करने वाला तथ्य यह है कि हर जगह मैंने पढ़ा है, मुझे लगता है कि "लंबे समय से चलने वाले कार्यों को संभालने के लिए मैन्युअल रूप से बनाए गए थ्रेड (या कस्टम थ्रेड पूल) का उपयोग करें, और अल्पकालिक कार्यों के लिए टीपीएल का उपयोग करें , या कार्यों को समानांतर प्रसंस्करण की आवश्यकता है। " क्या वास्तव में है एक लंबे समय तक चलने वाला कार्य? क्या वह 5 सेकंड, 60 सेकंड, एक घंटा है?

  • मैन्युअल बनाया धागे
  • नेट ThreadPool वर्ग

एक और मुद्दा TPL:

क्या समय सीमा मैं बनाने धागे के इन तीन तरीकों में से प्रत्येक का उपयोग करना चाहिए साथ

मैंने सोचा है कि निम्नानुसार है - कहें कि मेरे सर्वर में वास्तव में 20,000 ग्राहक जुड़े हैं, जिनमें से प्रत्येक प्रति सेकंड 1 आदेश भेजता है (जो एक या कई कार्यों में अनुवाद कर सकता है)। यहां तक ​​कि शक्तिशाली हार्डवेयर के साथ, क्या कोई मौका नहीं है कि मैं जो भी थ्रेड पूल/वर्क आइटम कतार में वर्कलोड का बहुत अधिक दबाव डाल सकता हूं, जिससे आखिरकार कतार धीरे-धीरे अधिकतम हो जाने के बाद आउटऑफमेमरी अपवाद उत्पन्न हो जाता है?

किसी भी अंतर्दृष्टि की सराहना की जाएगी।

+0

और औसत पर प्रत्येक आदेश कितनी देर तक प्रसंस्कृत किया जाएगा? – rene

+0

यह बात है - वास्तव में यह नहीं बता रहा है कि आदेश कब पूरा होगा। मुझे लगता है कि मुझे तदनुसार योजना बनाने के लिए पर्याप्त जानकारी मिली है। बेशक 20,000 ग्राहक एक लंबा शॉट है (5,000 इस तरह अधिक है), लेकिन यदि आवश्यक हो तो मैं भविष्य में स्केल करने के लिए तैयार होना चाहता हूं। आपकी प्रतिक्रियाओं के लिए आप सबका शुक्रिया। – slashp

+2

@ स्लैशप लांग रनिंग का अर्थ है "कुछ सौ मिलीसेकंड से अधिक", यानी। ऐसा कुछ जो आपके अन्य काम को बाधित करता है (और प्रसंस्करण के लिए महत्वपूर्ण विलंबता प्रस्तुत करता है)। यदि आप उदाहरण के लिए 5 एमएस विलंबता का लक्ष्य रखते हैं, तो 1 एमएमएस को "लंबे समय तक चलने" भी माना जा सकता है: डी भी, मैं यह इंगित करना चाहता हूं कि 20k टीसीपी क्लाइंट व्यावहारिक सीमा के करीब आ रहे हैं - प्रत्येक टीसीपी कनेक्शन को एक अलग बंदरगाह की आवश्यकता होती है, और आपके पास अधिकतम * अधिकतम * 65535 हैं - और वे बंद होने के लगभग 4 मिनट तक रहते हैं। आपको स्केलिंग (सर्वर प्रति अधिक कनेक्शन) की बजाय स्केलिंग (अधिक सर्वर) के बारे में सोचना पड़ सकता है। – Luaan

उत्तर

17

दरअसल, उस परिदृश्य के लिए सभी माध्यमिक हैं; पहली चीज़ आपको देखना चाहिए asyc-IO, उर्फ ​​.BeginRead(...) आदि; यह आपको आईओ पूरा करने वाले बंदरगाहों पर प्रतीक्षा करके धागे की संख्या को कम करने की अनुमति देता है - अधिक कुशल।

एक बार जब आपका पूरा संदेश हो, उस पैमाने पर मैं संदेश को कस्टम थ्रेड-पूल/सिंक्रनाइज़-कतार में फेंक दूंगा। मेरे पास नियमित धागे (पूल धागे या आईओसीपी नहीं) की नियंत्रित संख्या होगी जो प्रत्येक आइटम को संसाधित करने के लिए कतार की सेवा करेगी।

जैसा कि होता है मैं इस समय कुछ समान (निम्न पैमाने) कर रहा हूं; स्मृति विस्फोट को रोकने के लिए, मैंने कार्य कतार को पकड़ लिया है; अगर यह पूरा हो जाता है (यानी श्रमिक नहीं रह सकते हैं) तो आप आईओसीपी को थोड़ी देर के लिए ब्लॉक कर सकते हैं, शायद अंततः एक टाइमआउट के साथ जो क्लाइंट को आईओसीपी परत पर "बहुत व्यस्त" बताता है।

+0

+1 "कतार + सर्विसिंग थ्रेड्स" के लिए +1 - बहुत अच्छा तरीका होने की संभावना –

+1

क्षमा करें, मैं यह उल्लेख करना भूल गया कि मैं समझता हूं कि आईओसीपी नेटवर्किंग हिस्से के लिए उपयोग किया जाएगा, मैं सिर्फ कुछ पृष्ठभूमि देना चाहता हूं जो मैं पूरा करना चाहता हूं। मैं यह भी समझता हूं कि आईओसीपी का उपयोग करते समय मुझे ढेर विखंडन के बारे में सावधान रहने की आवश्यकता है जो आउटऑफमेमरी अपवाद भी पैदा कर सकता है। मुझे वास्तव में केवल तीन संरचनाओं का उपयोग करने के साथ-साथ "लंबे समय से चलने वाले" कार्य की परिभाषा के बारे में स्पष्टीकरण की आवश्यकता है। – slashp

+0

@slashp मैंने स्मृति मुद्दे पर कुछ विचार जोड़ने के लिए संपादित किया; चूंकि आप लगातार चलने की संभावना रखते हैं, आप अपने आप धागे के मालिक भी हो सकते हैं - थ्रेडपूल के साथ गड़बड़ से बचाता है, साथ ही आप उन्हें –

10

मुझे क्या भ्रमित है सबसे तथ्य यह है कि हर जगह मैंने पढ़ा है, मैं "एक मैन्युअल रूप से बनाई गई थ्रेड का उपयोग कार्यों 'लंबे समय से चल' संभाल करने के लिए (या कस्टम थ्रेड पूल), और उपयोग की तरह कुछ देखते है अल्पकालिक कार्यों के लिए टीपीएल, या कार्यों जो समानांतर प्रसंस्करण की आवश्यकता है। "

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

एक लंबे समय से चलने वाला कार्य वास्तव में क्या है? क्या वह 5 सेकंड, 60 सेकंड, घंटा है?

टीपीएल थ्रेडपूल के शीर्ष पर चलता है और टीपी अधिकतम 2 सेकंड प्रति सेकंड पर नए थ्रेड बनाएगा। तो लंबे समय से चल रहा है> = 500 एमएस


यहां तक ​​कि शक्तिशाली हार्डवेयर के साथ है, नहीं है इस बात की संभावना है कि मैं जो कुछ भी थ्रेड पूल/काम आइटम कतार में एक काम का बोझ की बहुत अधिक जोर दे रहा जा सकता है मेरे पास है,

हाँ, कोई थ्रेडिंग उपकरण 20k ग्राहकों आप शायद एक सर्वर फार्म की आवश्यकता होगी के साथ अपने वास्तविक क्षमता ...

विस्तार कर सकते हैं, एक विकल्प अपने डिजाइन ईए में शामिल करने के लिए rly ...

तो आपको शायद सॉकेट में गहरे होने से पहले डब्ल्यूसीएफ को एक अच्छा रूप देना चाहिए।

+0

नाम दे सकते हैं अब मैंने सोचा था कि थ्रेड शेड्यूलर हमेशा "LongRunning" विकल्प का सम्मान नहीं करेगा? "लंबे समय से चलने" की जानकारी के लिए धन्यवाद। – slashp

+0

@ स्लस लॉन्ग राइजिंग शेड्यूलर के लिए एक संकेत है, इसलिए मुझे लगता है कि इसे अनदेखा करने के लिए स्वतंत्र है, पूरे "नो लॉन्ग राइजिंग" चीज शेड्यूलर/लोड-बैलेंसिंग को परेशान करने के बारे में नहीं है। –

+1

भले ही लॉन्ग राइजिंग को एक संकेत के रूप में परिभाषित किया गया हो, लेकिन डिफ़ॉल्ट कार्यस्कूलर में वास्तविक कार्यान्वयन हमेशा एक नया धागा बनायेगा - http://coderkarl.wordpress.com/2012/12/13/long-running-tasks-and-threads/ देखें – Lummo

7

मार्क्स सुझाव वह तरीका है जो मैं करूँगा। लेकिन यदि आप एक सेकंड से अधिक समय लेते हैं और ग्राहक प्रति सेकंड एक अनुरोध भेजते हैं तो कतार लगातार बढ़ेगी।

उस स्थिति में मैं एक सर्वर को मुखौटा के रूप में उपयोग करता हूं जो ग्राहकों से सभी अनुरोध प्राप्त करता है और प्रतिक्रियाओं को एक अतुल्यकालिक तरीके से वापस भेजता है।

सर्वर सभी अनुरोधों को एक संदेश कतार में रखेगा जो कई अन्य सर्वरों द्वारा पढ़ा जाता है। वे सर्वर अनुरोधों को संभालते हैं और प्रतिक्रिया को किसी अन्य संदेश कतार में डालते हैं जो पहले सर्वर द्वारा पढ़ा जाता है।

एक और समाधान लोड संतुलन सर्वर का उपयोग करना होगा।

4

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

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

यह सुनिश्चित नहीं है कि आप प्रत्येक लंबे समय तक कितने CPU समय का उपभोग कर रहे हैं। यह आपके डिजाइन को प्रभावित करेगा, उदाहरण के लिए:

यदि प्रत्येक लंबी दौड़ मुख्य रूप से I/O पर अवरुद्ध हो रही है, तो आप ओवरलैप किए गए I/O या I/O समापन बंदरगाह पर प्रतीक्षा करने के लिए एक थ्रेड का उपयोग कर सकते हैं, फिर नए धागे को जगा सकते हैं प्रक्रिया पूर्ण I/O (एक थ्रॉटल सीमा तक)। प्रतीक्षा कनेक्शन की सेवा के लिए आपको थ्रेड की सीमित संख्या की आवश्यकता होगी।

यदि प्रत्येक लंबे समय से चलने वाला ऑपरेशन अन्य परिचालनों को पूरा करने की प्रतीक्षा करता है, तो विंडोज वर्कफ़्लो फाउंडेशन पर विचार करें।

यदि प्रत्येक लंबे समय से चलने वाला ऑपरेशन सीपीयू का उपभोग करता है, तो आप नहीं चाहते कि उनमें से बहुत से किसी भी समय चल रहे हों या यह आपके सर्वर को फेंक देगा। इस मामले में, एमएसएमक्यू और/या टीपीएल का उपयोग कतार कार्यों के लिए करें और सुनिश्चित करें कि एक ही समय में केवल कुछ ही चल रहे हैं।

इन सभी में, ऐसा लगता है कि आप ग्राहक कनेक्शन को खुले रख रहे हैं। सबसे खराब बात यह है कि प्रत्येक कनेक्शन के लिए एक थ्रेड अवरुद्ध रखना है। आपको सभी उत्कृष्ट कनेक्शनों की सेवा के लिए केवल सीमित संख्या में धागे का उपयोग करने के लिए थ्रेड-पूलिंग रणनीतियों को लागू करने की आवश्यकता होगी।

+0

महान प्रतिक्रिया, जानकारी के लिए धन्यवाद। – slashp