इस लेख में हम Manticore Search में लागू वर्तमान कार्यकर्ताओं के बारे में बात करते हैं और कार्यकर्ताओं के पैरामीटर को कैसे ट्यून करें।
Manticore Search में वर्तमान में दो मल्टी-प्रोसेसिंग मोड हैं जिन्हें निर्देश workers द्वारा नियंत्रित किया जाता है। डिफ़ॉल्ट MPM वर्तमान में thread_pool है, जिसमें threads का विकल्प है।
थ्रेड्स
मल्टी-प्रोसेसिंग मोड ‘ threads ’ में हर आने वाले नेटवर्क संयोग के लिए एक नया समर्पित थ्रेड बनाया जाता है। थ्रेड सक्रिय रहता है जब तक क्लाइंट अटकता नहीं - अर्थात, जब तक संयोग जीवित है। इस समय, थ्रेड आने वाले क्वेरियों को संयोग से निष्पादित करेगा।
डिफ़ॉल्ट रूप से, इंजन अनलिमिटेड संख्या में थ्रेड्स स्पॉन करेगा - अगर ऑपरेटिंग सिस्टम इसकी अनुमति देता है। जबकि यह अच्छा लग सकता है, वास्तव में अनलिमिटेड थ्रेड बनाने की अनुमति देना कुछ लागतों के साथ आता है। सबसे पहले, थ्रेड बनाने/नष्ट करने में एक CPU लागत होती है। जबकि यह फोरक्स की तुलना में कम है, यह फिर भी मौजूद है।
प्रति सेकंड सैकड़ों या हजारों थ्रेड्स स्पॉन करने से सिस्टम के प्रदर्शन पर प्रभाव पड़ सकता है, उपलब्ध CPU कोर के आधार पर। उपलब्ध कोरों की तुलना में थ्रेड्स की अधिक संख्या होने पर ये थ्रेड्स संसाधनों के लिए लड़ेंगे - एक CPU कोर, दूसरा स्टोरेज हो सकता है।
उदाहरण के लिए, यदि हमारे पास 16 कोर का सिस्टम है, लेकिन हम 160 सर्च थ्रेड्स स्पॉन करने की अनुमति देते हैं, तो इसका अर्थ है 10 थ्रेड्स प्रति CPU कोर। थ्रेड्स एक साथ नहीं चलेंगे, लेकिन उन्हें CPU कोर को उनके लिए चक्र आवंटित करने के लिए कतार में इंतजार करना होगा। स्टोरेज की तरफ, हमारे पास इससे डेटा पढ़ने के लिए 160 संभावित अनुरोधकर्ता हो सकते हैं। यदि स्टोरेज थ्रेड्स को बिना देरी (लेटेंसी) के सेवा देने में असमर्थ है, तो देरी CPU कोरों पर आवंटन को प्रभावित कर सकती है क्योंकि एक थ्रेड को CPU कोर पर इसकी गणनाएँ निष्पादित करने के लिए हरी रोशनी मिल सकती है, लेकिन उसे डेटा के लिए इंतजार करना पड़ता है।
max_children सेटिंग को एक सीमा निर्धारित करने की अनुमति देती है कि कितने थ्रेड्स एक साथ सक्रिय हो सकते हैं। जब सीमा पहुँचती है, तो इंजिन आने वाले कनेक्शनों को ‘maxed out’ त्रुटि के साथ अस्वीकार करना शुरू कर देगा। max_children का आकार निर्धारित करते समय, आपको ध्यान में रखना होगा कि जब क्लाइंट संयोग को बंद करता है तो थ्रेड को खत्म कर दिया जाता है। यदि संयोग idling है, तो थ्रेड सक्रिय रहेगा और max_children द्वारा गिना जाएगा। max_children को एक सीमा तक बढ़ाया जा सकता है जो सक्रिय क्वेरियों की संख्या संभालने के लिए सर्वर की क्षमताओं पर निर्भर करता है। इसमें प्रोसेसिंग क्षमताएँ (CPU) और IO ऑपरेशंस (स्टोरेज) शामिल हैं। एक सामान्य गलती है कि max_children को बहुत उच्च मूल्यों तक बढ़ाना। वहाँ एक बिंदु है, सिस्टम क्षमताओं के आधार पर, जब बहुत अधिक थ्रेड्स स्पॉन करने से सिर्फ क्वेरियों की गति धीमी होती है। यदि इंडेक्स और क्वेरियों के अनुकूलन के लिए और कुछ नहीं है, तो लोड को विभाजित करने के लिए एक नया सर्च सर्वर पर विचार किया जाना चाहिए।
Thread_pool
पिछले भाग में हमने थ्रेडिंग के लागत के बारे में बात की और यह कि कनेक्शन थ्रेड्स को जीवित रख सकते हैं भले ही उनका उपयोग न किया जाए।
थ्रेड्स का प्रबंधन करने की एक अलग रणनीति यह है कि हर कनेक्शन के लिए एक थ्रेड नहीं बनाया जाए, बल्कि काम करने के लिए थ्रेड्स का एक पूल का उपयोग किया जाए। इस मामले में, काम करने वाले थ्रेड्स आने वाले कनेक्शनों से जुड़े नहीं होते हैं क्योंकि कनेक्शनों को थ्रेड्स के एक अलग वर्ग द्वारा संभाला जाता है। जब डेमॉन प्रारंभ होता है, तो यह कई थ्रेड्स बनाता है। आने वाले नेटवर्क कनेक्शन को नेटवर्क थ्रेड्स द्वारा संभाला जाता है, उनका काम कनेक्शनों से क्वेरियों को प्राप्त करना और उन्हें पूल के थ्रेड्स को रूट करना होता है।
यदि पूल बहुत व्यस्त है (सभी कार्यकर्ता क्वेरियों को संसाधित कर रहे हैं), तो नई क्वेरियाँ पेंडिंग क्यू में भेजी जाती हैं। सर्वर ‘max out’ हो जाएगा यदि पेंडिंग क्यू भर जाती है। डिफ़ॉल्ट रूप से, कोई सीमा निर्धारित नहीं की गई है,हालांकि अधिक समय तक कतार में डालना कुछ नहीं करता जो कि लंबे समय तक लेने वाले क्वेरियों का। यह एक अच्छी विचार है कि सर्वर को यह संकेत देने के लिए कि वह अधिक क्वेरियाँ प्राप्त कर रहा है जिन्हें वह संभाल नहीं सकता, कतार पर एक सीमा हो। यह निर्देश queue_max_length के साथ सेट किया जा सकता है। थ्रेड्स मॉडल में max_children की तुलना में, जहां सर्वोत्तम स्थिति एक निश्चित संख्या के खुले कनेक्शनों के बाद शुरू होती है, थ्रेड_पूल के मामले में, डेमॉन सक्रिय क्वेरियों के बाद ‘max out’ शुरू करेगा जो कि max_children (पूल में थ्रेड्स की संख्या) + queue_max_length से अधिक हो।
thread_pool के मामले में, max_children निर्देश पूल में थ्रेड्स की संख्या को परिभाषित करता है, जो डेमॉन प्रारंभ पर बनाई जाती हैं। डिफ़ॉल्ट रूप से, CPU कोरों की संख्या का 1.5x मान उपयोग किया जाता है। max_children को उच्च मान विकल्प व्यावसायिक या सर्वर की क्षमता को बढ़ाएगा नहीं। चूंकि ये थ्रेड्स केवल प्रोसेसिंग करते हैं, उन्हें जल्दी से CPU तक पहुँच प्राप्त करने की आवश्यकता है।
उच्च मान सेट करने से पहले अनुभाग की तरह, CPU विवाद और धीमी प्रदर्शन की ओर ले जाएगा, बल्कि डेमॉन की धीमी प्रारंभ भी। थ्रेड्स मोड की तुलना में, जहां max_children को CPU कोरों की संख्या के कई गुना सेट किया जा सकता है और कई सौ के संदर्भ में मान बनाना समझ में आता है, थ्रेड_पूल के मामले में कोरों की संख्या के 2-3 गुना जाना समझ में नहीं आता।
डिफ़ॉल्ट रूप से, नेटवर्क कनेक्शनों को संभालने के लिए एक समर्पित थ्रेड का उपयोग किया जाता है। थ्रेड का कार्य सामान्यतः आसान होता है, क्योंकि यह केवल थ्रेड_pool के लिए प्रॉक्सी के रूप में कार्य करता है, और सामान्यत: यह अच्छे मात्रा में ट्रैफ़िक को सहन कर सकता है। नेटवर्क थ्रेड्स की संख्या को net_workers निर्देश के साथ बढ़ाया जा सकता है। नेटवर्क थ्रेड्स की संख्या बढ़ाने से उन सेटअप के लिए लाभ दिखा, जिनमें प्रति सेकंड प्रश्नों की अत्यधिक दर थी।
नेटवर्क थ्रेड(s) के पास कई फाइन ट्यूनिंग सेटिंग्स भी हैं। एक नेटवर्क थ्रेड हमेशा व्यस्त नहीं रह सकता है, क्योंकि ऐसे समय (उप-सेकंड की स्थिति में) हो सकते हैं जब यह प्रश्न प्राप्त नहीं करता है। थ्रेड सोने चला जाएगा और CPU के प्रति अपनी प्राथमिकता खो देगा। जागरूकता में बिताए गए समय या CPU पर अपनी जगह वापस पाने के लिए समय छोटा होता है, लेकिन उच्च प्रदर्शन के लिए हर मिलीसेकंड महत्वपूर्ण होता है।
इससे उबरने के लिए, एक व्यस्त लूप को net_wait_tm निर्देश के साथ सक्रिय किया जा सकता है। यदि net_wait_tm मान सकारात्मक है, तो थ्रेड CPU को हर 10*net_wait_tm पर ‘टिक’ करेगा (जहां net_wait_tm मान मिलीसेकंड का प्रतिनिधित्व करता है)। यदि net_wait_tm शून्य है, तो व्यस्त लूप निरंतर चलता है - यह ध्यान देने योग्य है कि यह अतिरिक्त CPU उपयोग उत्पन्न करेगा, भले ही नेटवर्क थ्रेड को बहुत अधिक ट्रैफ़िक प्राप्त न हो। व्यस्त लूप को अक्षम करने के लिए, -1 का नकारात्मक मान उपयोग किया जाना चाहिए। डिफ़ॉल्ट रूप से, net_wait_tm का मान 1 है, जो अर्थ है कि व्यस्त लूप हर 10ms पर टिक करता है।
नेटवर्क थ्रेड को भी थ्रॉटल किया जा सकता है। विकल्प net_throttle_accept एक सीमा लागू करता है कि नेटवर्क थ्रेड एक बार में कितने क्लाइंट स्वीकार कर सकता है और net_throttle_action स्पष्ट करता है कि प्रति पुनरावृत्ति कितने अनुरोधों को संसाधित करना है। डिफ़ॉल्ट रूप से, कोई सीमा लागू नहीं की जाती है। नेटवर्क थ्रेड को थ्रॉटल करना उच्च लोड परिदृश्यों के मामलों में समझदारी है।
एक पहलू जो कुछ गलतफहमी का कारण बनता है वह है max_children और dist_threads के बीच का संबंध। dist_threads कुछ ऑपरेशन, जैसे कि स्थानीय distributed इंडेक्स, snippets के साथ load_files या CALL PQ आदेश के लिए मल्टी-थ्रेडिंग का जिम्मेदार होता है। हालांकि ये उप-प्रसंस्करण थ्रेड होते हैं और ये max_children निर्देश के लिए गणना नहीं किए जाते हैं, जो केवल मुख्य प्रश्न थ्रेड्स की गणना करता है।