2010-01-09 9 views
88

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

एपोल और विकल्पों के बीच दो दर्जन तुलनाओं को पढ़ना दर्शाता है कि एपोल स्पष्ट रूप से गति और स्केलेबिलिटी के लिए चैंपियन है, विशेष रूप से यह एक रैखिक फैशन में शानदार है जो शानदार है। उस ने कहा, प्रोसेसर और मेमोरी उपयोग के बारे में क्या, अभी भी चैंपल है?

उत्तर

180

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

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

एपोल की लागत फाइल डिस्क्रिप्टरों की संख्या के करीब है जो वास्तव में उन पर घटनाएं होती हैं। यदि आप 200 फ़ाइल डिस्क्रिप्टरों की निगरानी कर रहे हैं, लेकिन उनमें से केवल 100 में ईवेंट हैं, तो आप केवल (100 मोटे तौर पर) उन 100 सक्रिय फ़ाइल डिस्क्रिप्टरों के लिए भुगतान कर रहे हैं। यह वह जगह है जहां एपोल चुनने पर अपने प्रमुख फायदों में से एक पेश करता है। यदि आपके पास हजारों ग्राहक हैं जो अधिकतर निष्क्रिय हैं, तो जब आप चुनते हैं तो आप अभी भी उनमें से एक हजार के लिए भुगतान कर रहे हैं। हालांकि, एपोल के साथ, ऐसा लगता है कि आपके पास केवल कुछ ही हैं - आप केवल उन लोगों के लिए भुगतान कर रहे हैं जो किसी भी समय सक्रिय हैं।

इसका मतलब यह है कि एपोल अधिकांश वर्कलोड के लिए कम CPU उपयोग का कारण बन जाएगा। जहां तक ​​स्मृति उपयोग जाता है, यह टॉस अप का थोड़ा सा है। select एक अत्यधिक कॉम्पैक्ट तरीके (एक फ़ाइल प्रतिलेखक प्रति बिट) में सभी आवश्यक जानकारी का प्रतिनिधित्व करने के लिए प्रबंधन करता है। और select के साथ आप कितने फ़ाइल डिस्क्रिप्टर का उपयोग कर सकते हैं, इस पर FD_SETSIZE (आमतौर पर 1024) सीमा का अर्थ है कि आप select (पढ़ने, लिखने, अपवाद) के साथ उपयोग किए जा सकने वाले तीन एफडी सेटों में से प्रत्येक के लिए 128 बाइट्स कभी नहीं व्यतीत करेंगे। उन 384 बाइट्स अधिकतम की तुलना में, एपोल एक सुअर की तरह है। प्रत्येक फ़ाइल डिस्क्रिप्टर को बहु-बाइट संरचना द्वारा दर्शाया जाता है। हालांकि, पूर्ण शब्दों में, यह अभी भी बहुत मेमोरी का उपयोग नहीं करेगा। आप कुछ दर्जन किलोबाइट्स (लगभग 20k प्रति 1000 फ़ाइल डिस्क्रिप्टर, मुझे लगता है) में फ़ाइल डिस्क्रिप्टर की एक बड़ी संख्या का प्रतिनिधित्व कर सकते हैं। और आप इस तथ्य में भी फेंक सकते हैं कि आपको select के साथ उन सभी बाइट्स को खर्च करना होगा यदि आप केवल एक फ़ाइल डिस्क्रिप्टर की निगरानी करना चाहते हैं लेकिन इसका मान 1024 होना होता है, एपोल के साथ वेरास केवल 20 बाइट खर्च करेंगे। फिर भी, ये सभी संख्याएं बहुत छोटी हैं, इसलिए इससे कोई फर्क नहीं पड़ता है।

और एपोल का वह अन्य लाभ भी है, जो शायद आप पहले ही जानते हैं कि यह FD_SETSIZE फ़ाइल डिस्क्रिप्टर तक ही सीमित नहीं है। आप इसे जितने फ़ाइल डिस्क्रिप्टरों की निगरानी के लिए उपयोग कर सकते हैं। और यदि आपके पास केवल एक फ़ाइल डिस्क्रिप्टर है, लेकिन इसका मान FD_SETSIZE से बड़ा है, तो एपोल भी उसके साथ काम करता है, लेकिन select नहीं करता है।

बेतरतीब ढंग से, मैं भी हाल ही में एक मामूली कमी epoll करने की खोज की है select या poll की तुलना में।हालांकि इनमें से कोई भी तीन एपीआई सामान्य फाइलों का समर्थन नहीं करता है (यानी, फाइल सिस्टम पर फाइलें), select और poll इस तरह के वर्णनकर्ताओं को हमेशा पठनीय और हमेशा लिखने योग्य के रूप में रिपोर्ट करने के रूप में समर्थन की कमी प्रस्तुत करते हैं। यह उन्हें किसी भी सार्थक प्रकार के गैर-अवरुद्ध फाइल सिस्टम I/O के लिए अनुपयुक्त बनाता है, जो एक प्रोग्राम है जो select या poll का उपयोग करता है और फाइल सिस्टम से फ़ाइल डिस्क्रिप्टर का सामना करना पड़ता है कम से कम काम करना जारी रखेगा (या यदि यह विफल हो जाता है, तो यह नहीं होगा select या poll) के कारण हो, हालांकि शायद यह सर्वोत्तम प्रदर्शन के साथ नहीं है।

दूसरी ओर, epoll ऐसी फ़ाइल डिस्क्रिप्टर की निगरानी करने के लिए पूछे जाने पर एक त्रुटि (EPERM, स्पष्ट रूप से) के साथ तेजी से विफल हो जाएगा। कड़ाई से बोलते हुए, यह शायद ही गलत है। यह केवल एक स्पष्ट तरीके से समर्थन की कमी को संकेत दे रहा है। आम तौर पर मैं स्पष्ट विफलता की शर्तों की सराहना करता हूं, लेकिन यह एक अनियंत्रित है (जहां तक ​​मैं कह सकता हूं) और परिणामस्वरूप पूरी तरह से खराब प्रदर्शन के परिणामस्वरूप एक पूरी तरह से टूटा हुआ एप्लिकेशन होता है।

प्रैक्टिस में, मैंने देखा है कि एकमात्र जगह यह है कि stdio के साथ बातचीत करते समय। कोई उपयोगकर्ता stdin या stdout को सामान्य फ़ाइल से/रीडायरेक्ट कर सकता है। जबकि पहले stdin और stdout एक पाइप होता - एपोल द्वारा समर्थित बस ठीक है - यह तब एक सामान्य फ़ाइल बन जाता है और एपोल जोर से विफल रहता है, एप्लिकेशन को तोड़ देता है।

+0

बहुत अच्छा जवाब। पूर्णता के लिए 'मतदान' के व्यवहार के बारे में स्पष्ट होने पर विचार करें? – quark

+6

साधारण फाइलों से पढ़ने के व्यवहार पर मेरे दो सेंट: मैं आम तौर पर प्रदर्शन में गिरावट के लिए पूरी तरह विफलता पसंद करता हूं। इसका कारण यह है कि विकास के दौरान यह पता लगाने की अधिक संभावना है, और इस प्रकार सही तरीके से काम किया जाता है (वास्तविक फ़ाइलों के लिए I/O करने का वैकल्पिक तरीका कहकर)। निश्चित रूप से वाईएमएमवी: ध्यान देने योग्य मंदी नहीं हो सकती है जिसमें मामले की विफलता बेहतर नहीं है। लेकिन नाटकीय मंदी जो केवल विशेष मामलों में होती है, विकास के दौरान पकड़ना बहुत कठिन हो सकता है, इसे वास्तव में तैनात किए जाने पर एक समय बम के रूप में छोड़ दिया जा सकता है। – quark

+1

बस अपना संपादन पूरी तरह से पढ़ना है। एक मायने में मैं इस बात से सहमत हूं कि शायद यह पूर्ववर्ती नहीं है कि वह अपने पूर्ववर्तियों की नकल न करें, लेकिन फिर मैं उस देव की कल्पना कर सकता हूं जिसने एपीआरएम त्रुटि को लागू किया था "सिर्फ इसलिए कि यह हमेशा टूट गया है, यह मेरा तोड़ने का अधिकार नहीं है कुंआ।" और फिर भी एक और काउंटर तर्क, मैं एक रक्षात्मक प्रोग्रामर हूं जो 1 + 1 से पहले कुछ भी संदिग्ध है और मैं इस तरह से कोड को असफल असफलताओं की अनुमति देता हूं। कर्नेल आग को उम्मीद की त्रुटि से बाहर रखना अच्छा या विचारशील नहीं है। – David

3

मेरी कंपनी के परीक्षणों में, एपोल() के साथ एक मुद्दा आया, इस प्रकार चयन की तुलना में एक ही लागत।

जब एक समय समाप्ति के साथ नेटवर्क से पढ़ने का प्रयास, एक epoll_fd (बजाय एक fd_set के) बनाने, और epoll_fd को fd जोड़ने, ज्यादा एक fd_set (जो एक साधारण malloc है) बनाने से ज्यादा महंगा है।

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

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

+5

लेकिन अगर आप 10k + रेंज में फ़ाइल डिस्क्रिप्टर मान रखते हैं तो आप 'select() 'का उपयोग भी नहीं कर सकते हैं - जब तक कि आप FD_SETSIZE को बदलने के लिए अपने सिस्टम को आधा नहीं देते - तो मुझे आश्चर्य है कि यह रणनीति बिल्कुल कैसे काम करती है। आपके द्वारा वर्णित परिदृश्य के लिए, मैं शायद 'मतदान()' को देखता हूं जो 'epoll()' की तरह 'चयन() 'की तरह अधिक है - लेकिन FD_SETSIZE सीमा को हटा देता है। –

+0

यदि आप 10K रेंज में फ़ाइल डिस्क्रिप्टर मान रखते हैं तो आप चयन() का उपयोग कर सकते हैं, क्योंकि आप एक FD_SET malloc() कर सकते हैं। वास्तव में, चूंकि FD_SETSIZE संकलित समय है और वास्तविक एफडी सीमा रनटाइम पर है, FD_SET का केवल सुरक्षित उपयोग FD_SET के आकार के विरुद्ध फ़ाइल डिस्क्रिप्टर की संख्या की जांच करता है, और यदि कोई Fall_SET है तो malloc (या नैतिक समतुल्य) करता है बहुत छोटा। जब मैंने इसे ग्राहक के साथ उत्पादन में देखा तो मुझे आश्चर्य हुआ। 20 वर्षों तक प्रोग्रामिंग सॉकेट के बाद, मैंने जो भी कोड लिखा होगा - और वेब पर अधिकांश ट्यूटोरियल असुरक्षित हैं। –

+5

यह किसी भी लोकप्रिय प्लेटफॉर्म पर, जहां तक ​​मुझे पता है, यह सच नहीं है। जब आपका * सी * लाइब्रेरी संकलित हो जाती है तो 'FD_SETSIZE' एक संकलित समय निरंतर सेट होता है। यदि आप अपना आवेदन बनाते समय इसे एक अलग मूल्य पर परिभाषित करते हैं तो आपका आवेदन और सी लाइब्रेरी असहमत होगी और चीजें खराब हो जाएंगी। यदि आपके पास दावा है कि 'FD_SETSIZE' को फिर से परिभाषित करना सुरक्षित है, तो मुझे उनको देखने में दिलचस्पी होगी। –