blog-post

Manticore Buddy: चुनौतियाँ और समाधान

Hey there! 🤗 हम उम्मीद करते हैं कि आपने पहले ही हमारे Buddy Intro को देख लिया होगा और यह समझ लिया होगा कि यह कैसे काम करता है। हम अपने सफर और अनुभव साझा करना चाहते हैं जो हमें इसे विकसित करते समय मिले और जिन चुनौतियों का हम सामना कर रहे थे।

Manticore Software में, हमें दो मुख्य चुनौतियों का सामना करना पड़ा:

  • Manticore Search का विस्तार करना बिना C++ में संशोधन किए गैर-प्रदर्शन-महत्वपूर्ण सुविधाओं के साथ।
  • सुधार और नई सुविधा कार्यान्वयन में योगदान करना आसान बनाना।

हम एक समाधान खोजने के लिए दृढ़ थे। तो, चलिए हम अपनी यात्रा में Buddy को विकसित करने और जिन मुद्दों का सामना किया, उसमें गोताखोरी करते हैं। तैयार हैं? चलिए शुरू करते हैं!

यात्रा की शुरुआत

हमारी यात्रा ने मुद्दे के करीब से निरीक्षण करने से शुरू की। हालाँकि Manticore Search एक असाधारण खोज डेटाबेस उत्पाद है, लेकिन हमें वांछित गति पर नई सुविधाएँ जारी करने में कठिनाई होती थी क्योंकि कोडबेस C++ में लिखा गया है। C++ कोड लिखने में डेटा संरचनाओं, बाइट्स, मशीन के कार्य करने के तरीके का गहरा ज्ञान, संकलन, डिबगिंग, और इसे लिखने के लिए सबसे अच्छा तरीका खोजने के लिए निम्न-स्तरीय अंतःक्रिया की आवश्यकता होती है, जो बहुत अधिक समय लेती है लेकिन परिणामस्वरूप प्रोग्राम निष्पादन तेज होता है। इससे विकास प्रक्रिया में भारी देरी हुई। हालांकि C++ प्रदर्शन के लिए एक बेहतरीन विकल्प है, इसे विकसित करने में समय लगता है। हम तेजी से आगे बढ़ना चाहते थे, अधिक सुविधाएँ भेजना चाहते थे, और ऐसा लगातार करना चाहते थे।

हमारे मूल searchd प्रक्रिया के लिए एक साथी बनाने का विचार आया, जो Manticore Search से असफल प्रश्नों को संसाधित कर सके और मूल ग्राहक को परिणाम लौटा सके। हमें यह तय करने में अधिक समय नहीं लगा कि किस भाषा का उपयोग किया जाए और कई कारणों से PHP पर सहमति बनाई:

  • मुख्य टीम के अधिकांश सदस्य इससे परिचित थे, इसलिए इसे काम करने में कम समय लगेगा।
  • PHP तेज है, खासकर नवीनतम संस्करण (8+) के साथ, भले ही हमें Buddy से प्रदर्शनकारी निष्पादन की आवश्यकता नहीं थी। यह Python या JavaScript से तेज है, इसलिए यह हमारी आवश्यकताओं के लिए एक अच्छा विकल्प था।
  • PHP केवल तेज नहीं है बल्कि सरल भी है, जो भविष्य की पारिस्थितिकी तंत्र में योगदान के लिए आवश्यक विशेषज्ञता के स्तर को कम करता है।

इसलिए हमने PHP का चयन किया और यह समझने के लिए बुनियादी कोड लागू करना शुरू किया कि हमें बाद में क्या आवश्यक होगा।

हम अभी भी प्रदर्शन-महत्वपूर्ण सुविधाओं को विकसित करने के लिए C++ का उपयोग करते हैं। C++ उन कार्यों के लिए आदर्श है जिन्हें गति की आवश्यकता होती है। ऐसे कार्यों के लिए जिन्हें अधिक गति की आवश्यकता नहीं है, Buddy सबसे उपयुक्त विकल्प है।

यह Buddy के निर्माण का तरीका है। इसे संभव बनाने के लिए Manticore Search के C++ पक्ष पर, हमने searchd डेमॉन और Buddy PHP प्रक्रिया के बीच एक अलग लूप और संचार लागू किया CURL एक्सटेंशन का उपयोग करके। हमने एक साधारण JSON आंतरिक प्रोटोकॉल विकसित किया, जिससे प्रश्नों को Buddy तक पहुंचाया जा सके; यह इन प्रश्नों को संभालता है और हमें मूल ग्राहक को वापस भेजे जाने के लिए एक उपयुक्त प्रतिक्रिया भेजता है।

संचार प्रोटोकॉल को लागू करना

जब एक नई परियोजना शुरू करते हैं, तो लचीला रहना और अधिक योजना नहीं बनाना महत्वपूर्ण है। हमारे मामले में, हमने PHP में sockets एक्सटेंशन का उपयोग करके संचार का एक बुनियादी कार्यान्वयन शुरू किया। जबकि यह अच्छा काम कर रहा था, यह स्केलेबल नहीं था। हमारा लक्ष्य Manticore Search को Buddy से जोड़ना था, और यह सरल कार्यान्वयन हमें उस विचार का मूल्यांकन करने की अनुमति दी।

पहिया को फिर से आविष्कार करने के बजाय, हमने सिस्टम को अधिक स्केलेबल और नॉन-ब्लॉकिंग बनाने के विकल्पों पर शोध किया। हमने प्रारंभ में OpenSwoole पर विचार किया, लेकिन लाइसेंसी मुद्दे के कारण, हम इसका उपयोग नहीं कर सके। फिर हमें ReactPHP मिला, जिसमें उपयुक्त लाइसेंस था। इसलिए, हमने ReactPHP के साथ जाने का निर्णय लिया।

ReactPHP एक साधारण PHP फ्रेमवर्क है जो हमें async मोड में एक TCP सर्वर चलाने की अनुमति देता है।

यह विकल्प हमारे लिए अच्छा काम किया क्योंकि इससे हमें कई अनुरोधों को एक साथ संभालने और सिस्टम को आसानी से स्केल करने की अनुमति मिली।

इसके बाद, हमने अपने सरल Buddy MVP को फिर से लिखा और एक कोर संरचना बनाई जो भविष्य में नए SQL आदेशों को संभालना आसान बना देगी। प्रक्रिया निम्नलिखित है:

  • Manticore Search उपयोगकर्ता से एक SQL प्रश्न प्राप्त करता है और इसे संभालने की कोशिश करता है।
  • यदि Manticore Search प्रश्न को संभाल सकता है, तो यह बिना Buddy को शामिल किए ग्राहक को प्रतिक्रिया लौटाता है।
  • यदि Manticore Search प्रश्न को संभाल नहीं सकता, तो यह Buddy को इनपुट प्रश्न और किसी भी त्रुटियों के बारे में सभी जानकारी के साथ एक विशेष संरचना भेजता है।
  • Buddy संरचना को पार्स करता है और जांचता है कि क्या इसके लिए एक हैंडलर है। यदि नहीं है, तो यह वही त्रुटि लौटाता है जो Manticore Search ग्राहक को भेजेगा।
  • यदि सब कुछ ठीक है और हमारे पास प्रश्न को संभालने के लिए एक कार्यान्वयन है, तो हम प्रक्रिया को दो चरणों में विभाजित करते हैं: आवश्यक डेटा के साथ अनुरोध तैयार करना और इसे हैंडलर लॉजिक के साथ संभालना। अनुरोध एक साधारण संरचना है जो पूर्वनिर्धारित चर और इनपुट SQL प्रश्न से पार्स किए गए इनपुट पैरामीटर का प्रतिनिधित्व करती है। यदि कुछ गलत होता है, तो यह विफल हो सकता है और ग्राहक को त्रुटि लौटा सकता है।
  • फिर हैंडलर अनुरोध प्राप्त करता है, आवश्यक कार्य करता है, और HTTP अनुरोध को अंतिम परिणाम वापस करता है।

यह प्रणाली बनाए रखने में आसान, सरल है, और नई कार्यक्षमता के साथ आसानी से विस्तारित की जा सकती है। हालाँकि, इस दृष्टिकोण के साथ एक समस्या है। यदि हमारे पास कुछ भारी है या Buddy में इंतजार करने की आवश्यकता है, तो यह समवर्ती अनुरोधों को धीमा कर सकता है। इसका कारण यह है कि भले ही async समानांतर नहीं है, PHP अभी भी कोड को अवरोधित करता है, और ReactPHP async दृष्टिकोण का अनुकरण करने के लिए fibers का उपयोग करता है। हम इस मुद्दे पर अगली अनुभाग में अधिक विस्तार से चर्चा करेंगे।

PHP में async समस्या और समवर्ती के लिए स्केल

भारी लोड को संभालने के लिए, Manticore Search में हमारी टीम को एक ऐसे समाधान की आवश्यकता थी जो ReactPHP से अधिक अनुरोधों को संभाल सके। जबकि ReactPHP ने असिंक्रोनस HTTP सर्वर लागू करने और कुछ समवर्तीता को संभालने के लिए काम किया, यह पर्याप्त स्केलेबल नहीं था। एक त्वरित खोज के बाद, हमने parallel एक्सटेंशन का चयन किया pthreads पर इसके रखरखाव और विश्वसनीयता के कारण।

लेकिन पैरलेल क्या है? यह समांतरकरण के बारे में है, स्वतंत्र रंटाइम्स बनाना जो समांतर चलने वाले थ्रेड्स का प्रतिनिधित्व करता है। ये थ्रेड्स चैनल के माध्यम से संचार कर सकते हैं, जो पैरलेल प्रदान करता है, जिससे हम मुख्य रीएक्टपीएचपी लूप प्रोसेस से पैरेलल और अलग थ्रेड में डेटा भेज सकें बिना पहिया फिर से बनाने के।

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

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

हालांकि हम आसानी से प्रदर्शन और समवर्ती समस्या को हल करने में सफल रहे, लेकिन हम एक और चुनौती का सामना कर रहे थे: तैनाती। सभी ऑपरेटिंग सिस्टम नवीनतम पीएचपी 8 संस्करण का समर्थन नहीं करते हैं, और कुछ असाधारण एक्सटेंशन मानक इंस्टॉलेशन में शामिल नहीं होते हैं। लेकिन हमनें एक समाधान खोजा, और आप भी कर सकते हैं।

मैन्टिकोर-एक्जिक्यूटर को नमस्ते कहें

हमने शोध किया कि उपभोक्ताओं को नए उपकरण को भेजने का एक दर्द रहित तरीका खोजा जा सके और एक महान दृष्टिकोण खोजा - दोनों <strong>पीएचपी</strong> और Buddy को एक एकल स्थैतिक बाइनरी में संकलित करना । इसमें पीएचपी को इसके स्रोतों में इंजेक्ट करना और एक बाइनरी बनाना शामिल था जो चल सके। हालाँकि, हमें एक बाधा का सामना करना पड़ा क्योंकि हम विभिन्न लाइसेंस - पीएचपी 3.01 और GPL 2.0 - को मिलाने की कोशिश कर रहे थे - जो संभव नहीं था। इसके परिणामस्वरूप, हमने पीएचपी को पूर्व-निर्मित करने, इसे स्थैतिक रूप से लिंक करने और इसे मैन्टिकोर-एक्जिक्यूटर नाम दिया।

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

हमने GCC का उपयोग क्यों किया? यह पीएचपी और इसके एक्सटेंशन को संकलित करने के लिए आवश्यक था। समस्या यह थी कि हमें स्थैतिक रूप से लिंक करने के लिए एक स्थैतिक रूप से निर्मित GCC की आवश्यकता थी, जो सीधा नहीं है और इसके लिए बहुत काम की आवश्यकता होती है। इसके परिणामस्वरूप, हमने विकल्पों की तलाश की।

खुशी से, हमने MUSL और Alpine खोजा, जिसने हमें सभी आवश्यक एक्सटेंशनों और लाइब के साथ पीएचपी का एक पूर्ण स्थैतिक संस्करण बनाने की अनुमति दी, बिना किसी कठिनाई के! इसके अलावा, यह किसी भी लिनक्स वितरण पर काम करता है।

Alpine Linux सी प्रोग्राम बनाने के लिए एक उत्कृष्ट विकल्प है क्योंकि इसका आकार छोटा और हल्का होता है, जिससे यह सीमित संसाधनों वाले सिस्टम जैसे एम्बेडेड डिवाइस या कंटेनरों के लिए उपयुक्त हो जाता है। इसके अलावा, Alpine Linux सुरक्षित है। यह एक हार्डन kernel और कम पैकेजों का उपयोग करता है, जिससे हमले की सतह को सीमित कर दिया जाता है और यह सुरक्षा खतरों के प्रति कम संवेदनशील हो जाता है। यह C प्रोग्रामों के लिए विशेष रूप से महत्वपूर्ण है, जो सुरक्षा कमजोरियों के प्रति संवेदनशील हो सकते हैं।

इसके अलावा, Alpine Linux अपने मानक C लाइब्रेरी के रूप में MUSL libc का उपयोग करता है, जो एक हल्की और कुशल C लाइब्रेरी है जो अन्य C लाइब्रेरी की तुलना में तेज और अधिक कुशल कोड में परिणत होती है।

इसके परिणामस्वरूप, हमने इसका उपयोग किया और डॉकर में एक Alpine छवि का उपयोग करने के लिए कार्रवाइयाँ सेट कीं। इस दृष्टिकोण की खूबी यह है कि यह हमारे लिए ARM के लिए निर्माण करना भी आसान बना देता है क्योंकि डॉकर के पास buildx कमांड है, जो हमें निर्माण के लिए QEMU का उपयोग करने की अनुमति देता है और AMD और ARM आर्किटेक्चर के लिए एक ही मशीन पर निर्माण के लिए समान प्रवाह को पूरा करता है! हमारी निर्माण धारा यहां देखें।

गिटहब क्रियाएँ सभी समर्थित ऑपरेटिंग सिस्टम के लिए पैकेज के निर्माण और तैनाती को स्वचालित करती हैं। उपयोगकर्ताओं के लिए, स्थापना सरल है: बस apt-get install manticore-executor या yum install manticore-executor चालाएं, और आपके पास उपयोग करने के लिए सभी आवश्यक पैकेज पूर्व-स्थापित पीएचपी संस्करण होगा। आसान!

हम अपना स्रोत कोड कैसे शिप करते हैं

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

जैसा कि आप याद करेंगे, हमने एक कस्टम PHP संस्करण विकसित किया, जिसे मैन्टिकोर-एक्जिक्यूटर कहा जाता है, जिसे भंडार से आसानी से स्थापित किया जा सकता है। हालाँकि, यह अभी भी उपयोगकर्ता के पास पूरे PHP एप्लिकेशन को प्रदान करने की समस्या का समाधान नहीं करता था।

हमने PHAR में एक समाधान पाया, जिसने हमें एक एकल फ़ाइल बनाने की अनुमति दी जिसे भंडार में एक पैकेज के रूप में जोड़ा जा सकता है। इसने स्थापना प्रक्रिया को सरल बना दिया। हालाँकि, यह सुनिश्चित करना कि सभी निर्भरताएँ अंतिम PHAR संग्रह में सही ढंग से शामिल की गई थीं, थोड़ा मुश्किल था। इसे हल करने के लिए, हमने एक बाहरी निर्माण प्रणाली बनाई और अलग कर दी, जिसे हम अपने मैन्टिकोर-बैकअप उपकरण के लिए भी उपयोग करते हैं।

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

सीखे गए सबक

  1. भविष्य के सफलता के बारे में अनिश्चित होने पर सॉफ़्टवेयर डिज़ाइन पैटर्न का उपयोग किए बिना एक सरल, बुनियादी समाधान से शुरू करें। पहले सत्यापन को प्राथमिकता दें और फिर पुनः कार्यान्वयन और अपडेट पर चक्र करें।
  2. PHP में समवर्तीता चुनौतीपूर्ण हो सकती है, लेकिन थ्रेडिंग और एसींक्रोनस ढांचे का उपयोग करने से उच्च थ्रूपुट प्राप्त करने में मदद मिल सकती है। अनुकूल प्रदर्शन के लिए, दोनों का उपयोग करने की सिफारिश की जाती है। थ्रेड्स के लिए पूर्व-निर्धारित रनटाइम्स का आवंटन वांछित प्रदर्शन प्राप्त करने में मदद कर सकता है।
  3. उपयोगकर्ताओं के लिए शिपिंग प्रक्रिया को सरल बनाएं। आवश्यक निर्देशों की संख्या को कम करें। हमारे मामले में, एक PHAR अर्काइव और सभी शामिल एक्सटेंशन के साथ एक बाइनरी ने हमारी कस्टम PHP के लिए समस्या का समाधान किया।
  4. नवीनतम विकास के शीर्ष पर रहने और अपने डेटा को सुरक्षित रखने के लिए PHP या अन्य उपकरणों के सबसे हाल के संस्करणों का उपयोग करें। पुराना सॉफ़्टवेयर हैक और सुरक्षा उल्लंघनों के लिए संवेदनशील हो सकता है। उन्नयन बेहतर प्रदर्शन, नवीनतम विशेषताएँ, और एक कुशल कोडिंग प्रक्रिया प्रदान करता है।
  5. उस समस्या को हल करने के लिए पैकेज खोजना और उनकी निर्भरताओं की जांच करना। निर्भरताओं के नरक से बचने के लिए न्यूनतम निर्भरताओं वाले पैकेज का चयन करें। कस्टम समाधान बनाने के बजाय छोटे पैकेज का उपयोग करें जैसे कि निर्माण ब्लॉक्स।

अंतिम परिणाम

Buddy के विकास के दौरान, हमें कई चुनौतियों का सामना करना पड़ा, जिन पर हमने उत्साह के साथ विजय प्राप्त की। यह उपकरण पूरी तरह से PHP में लिखा गया है और इसे एक OS पैकेज के रूप में शिप किया गया है, जिससे उपयोगकर्ताओं के लिए इसे स्थापित करना और हमारे लिए बनाए रखना और ऑटोमेटेड निर्माण करना बेहद आसान हो गया है, इसके लिए धन्यवाद GitHub Actions। जबकि उपकरण को और भी सरल बनाने के लिए सुधार की गुंजाइश है, हमारी कहानी यह दर्शाती है कि कैसे एक आसान रखरखाव और इंस्टॉल करने में आसान उपकरण बनाया जा सकता है, सब कुछ PHP की शक्ति के साथ।

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

मैंटीकोर सर्च इंस्टॉल करें

मैंटीकोर सर्च इंस्टॉल करें