मुझे हमेशा रूबी-ऑन-रेल्स (आरओआर) और ट्विटर पर इस ढांचे पर मंच के एक उज्ज्वल प्रतिनिधि के रूप में दिलचस्पी रही है। इस वर्ष 6 अप्रैल को, ट्विटर टीम पर RoR से जावा तक के खोज प्लेटफ़ॉर्म के पूर्ण परिवर्तन के बारे में एक ब्लॉग पोस्ट दिखाई दी। कैसे यह था के कट अनुवाद के तहत।
“2010 के वसंत में, ट्विटर सर्च टीम ने हमारे खोज इंजन को हमेशा बढ़ते ट्रैफ़िक की सेवा, अंतिम उपयोगकर्ता के लिए विलंबता को कम करने और हमारी सेवा की उपलब्धता बढ़ाने के लक्ष्य के साथ फिर से लिखना शुरू किया, जिससे नई खोज क्षमताओं को जल्दी से विकसित करने का अवसर मिला। नौकरी के हिस्से के रूप में, हमने एक नया
वास्तविक समय खोज इंजन लॉन्च किया, जो MySQL से
ल्यूसीन संस्करण में हमारे बैक-एंड को बदल रहा है। पिछले हफ्ते, हमने अपने रूबी-ऑन-रेल्स फ्रंट-एंड के लिए एक प्रतिस्थापन शुरू किया: एक जावा सर्वर जिसे हम ब्लेंडर कहते हैं। हमें यह घोषणा करते हुए प्रसन्नता हो रही है कि इस परिवर्तन ने खोज समय को 3 गुना घटा दिया है और इससे हमें आने वाले महीनों में खोज की कार्यक्षमता में लगातार वृद्धि करने का अवसर मिलेगा।
प्रदर्शन लाभ
Twitter Search दुनिया के सबसे व्यस्त खोज इंजनों में से एक है, जो प्रति दिन एक बिलियन से अधिक खोज क्वेरी की सेवा देता है। इस सप्ताह, हमने ब्लेंडर को तैनात करने से पहले, जापान में
#tsunami ने खोज प्रश्नों में महत्वपूर्ण वृद्धि और खोज से जुड़ी चोटियों में योगदान दिया। ब्लेंडर को लॉन्च करने के बाद, हमारे 95% देरी में 3 गुना की कमी हुई, 800ms से 250ms तक, और हमारे फ्रंट-एंड सर्वर पर सीपीयू लोड आधा हो गया। अब हमारे पास प्रति मशीन 10 गुना अधिक अनुरोध करने की क्षमता है। इसका मतलब यह है कि हम परिमाण के एक क्रम द्वारा कम फ्रंट सर्वर की समान संख्या को बनाए रख सकते हैं, जिससे हमारी फ्रंट-एंड सेवा की लागत कम हो सकती है।
ब्लेंडर को शुरू करने से पहले और बाद में खोज एपीआई में 95% देरी।बेहतर ट्विटर खोज वास्तुकला
प्रदर्शन लाभ को बेहतर ढंग से समझने के लिए, आपको पहले हमारे पूर्व रूबी-ऑन-रेल्स फ्रंट-एंड सर्वर की कमजोरियों को समझना होगा। उन्होंने एकल-पिरोया वर्कफ़्लो की एक निश्चित संख्या शुरू की, जिनमें से प्रत्येक ने निम्नलिखित किया:
- खोज क्वेरी पार्स की गई;
- सिंक्रोनस अनुरोधित खोज इंजन;
- एकत्र और परिणामों का गठन किया।
हम लंबे समय से जानते हैं कि सिंक्रोनस अनुरोध प्रसंस्करण मॉडल हमारे सीपीयू को अक्षम रूप से उपयोग करता है। समय के साथ, हमने अपने मुख्य रूबी कोड में काफी तकनीकी ऋण जमा किया है, जिससे कार्यक्षमता को जोड़ना और हमारे खोज इंजन की विश्वसनीयता में सुधार करना मुश्किल हो गया है। ब्लेंडर इन मुद्दों को हल करता है:
- पूरी तरह से अतुल्यकालिक एकत्रीकरण सेवा बनाएं। नेटवर्क I / O के पूरा होने की प्रतीक्षा में कोई सूत्र नहीं;
- वास्तविक समय की सेवा, शीर्ष ट्वीट सेवा और भौगोलिक सूचकांक सेवा जैसे बैक-एंड सेवाओं से परिणाम एकत्र करना;
- सेवाओं के बीच निर्भरता को और अधिक सटीक रूप से हल करना। वर्कफ़्लो स्वचालित रूप से बैक-एंड सेवाओं के बीच सकरात्मक निर्भरता को संभालता है।
निम्नलिखित आरेख ट्विटर खोज इंजन की वास्तुकला को दर्शाता है। एक वेबसाइट, एपीआई, या ट्विटर पर बाहरी ग्राहकों के अनुरोधों को एक हार्डवेयर लोड बैलेंसर के माध्यम से ब्लेंडर को भेजा जाता है। ब्लेंडर खोज अनुरोध को पार्स करता है और सेवाओं के बीच निर्भरता को संभालने के लिए वर्कफ़्लोज़ का उपयोग करते हुए इसे बैक-एंड सेवाओं तक पहुंचाता है। अंत में, सेवाओं से परिणाम ग्राहक की उपयुक्त भाषा में संयुक्त और गठित होते हैं।
ब्लेंडर के साथ ट्विटर सर्च आर्किटेक्चर।ब्लेंडर की समीक्षा
ब्लेंडर एक थ्रिफ्ट और एचटीटीपी सेवा है जो
नेट्टी पर निर्मित है, जो कि जावा में लिखित एक व्यापक रूप से स्केलेबल एनआईओ क्लाइंट-सर्वर लाइब्रेरी है, जो विभिन्न सर्वरों और क्लाइंट्स को जल्दी और आसानी से विकसित करने की अनुमति देता है। हमने अपने कई प्रतिस्पर्धियों जैसे मीना और जेट्टी से नेट्टी का चयन किया, क्योंकि इसमें अधिक पारदर्शी एपीआई, बेहतर प्रलेखन, और सबसे महत्वपूर्ण बात है, क्योंकि कई अन्य ट्विटर परियोजनाएं इस ढांचे का उपयोग करती हैं। थ्रिफ्ट के साथ काम करने के लिए नेट्टी के लिए, हमने एक साधारण थ्रिफ्ट कोडेक लिखा है, जो नेट्टी चैनल बफर से आने वाले थ्रिफ्ट अनुरोधों को डिकोड करता है, जब इसे एक सॉकेट से पढ़ा जाता है और एक सॉकेट को लिखे जाने पर आउटफिट के थ्रस्टिंग प्रतिक्रियाओं को एनकोड करता है। नेटी ने नेटवर्क सॉकेट से एक कनेक्शन को एनकैप्सुलेट करने के लिए चैनल नामक एक प्रमुख अमूर्तता का परिचय दिया, जो कई I / O संचालन करने के लिए एक इंटरफ़ेस प्रदान करता है, जैसे पढ़ना, लिखना, कनेक्ट करना और बाइंड करना। सभी चैनल I / O संचालन प्रकृति में अतुल्यकालिक हैं। इसका मतलब यह है कि कोई भी I / O कॉल तुरंत ChannelFuture के एक उदाहरण के साथ लौटता है जो रिपोर्ट करता है कि अनुरोधित I / O ऑपरेशन सफल, असफल या रद्द किए गए हैं। जब नेट्टी सर्वर एक नया कनेक्शन स्वीकार करता है, तो यह कनेक्शन को संभालने के लिए एक नया चैनल पाइपलाइन बनाता है। एक चैनल पाइपलाइन चैनल हैंडलर्स का एक अनुक्रम है जो अनुरोध को संसाधित करने के लिए आवश्यक व्यावसायिक तर्क को लागू करता है। अगले भाग में, हम दिखाएंगे कि ब्लेंडर क्वेरी प्रोसेसिंग वर्कफ़्लो के लिए इन पाइपलाइनों को कैसे स्थानांतरित करता है।
वर्कफ़्लो लाइब्रेरी
ब्लेंडर में, वर्कफ़्लो उनके बीच निर्भरता के साथ बैक-एंड सेवाओं का एक सेट है जिसे एक आने वाले अनुरोध की सेवा के लिए संसाधित किया जाना चाहिए। ब्लेंडर स्वचालित रूप से उन दोनों के बीच निर्भरता को निर्धारित करता है, उदाहरण के लिए, यदि सेवा ए सेवा बी पर निर्भर करती है, तो ए पहले अनुरोध किया जाता है और इसके काम के परिणाम बी को प्रेषित किए जाते हैं। यह
निर्देशित चक्रीय ग्राफ के रूप में वर्कफ़्लोज़ का प्रतिनिधित्व करने के लिए सुविधाजनक है (नीचे आंकड़ा देखें)।
6 बैक-एंड सेवाओं के साथ नमूना ब्लेंडर वर्कफ़्लो।वर्कफ़्लो के उदाहरण में, हमारे पास 6 सेवाएँ हैं {s1, s2, s3, s4, s5, s6} जिनके बीच निर्भरताएँ हैं। S3 से s1 तक की सीधी रेखा का मतलब है कि s3 को s1 कहा जाने से पहले बुलाया जाना चाहिए, क्योंकि s1 को s3 के परिणामों की आवश्यकता होती है। इस तरह के एक काम करने वाले प्रोजेक्ट के लिए, ब्लेंडर लाइब्रेरी सेवाओं के अंतिम क्रम को निर्धारित करने के लिए
डीएजी पर
टोपोलॉजिकल सॉर्टिंग करती है, जो कि वह क्रम भी है जिसमें उन्हें बुलाया जाता है। उपरोक्त वर्कफ़्लो के लिए निष्पादन का क्रम {(s3, s4), (s1, s5, s6), (s2)} होगा। इसका मतलब यह है कि s3 और s4 को पहले चरण में समानांतर में बुलाया जा सकता है; जब वे परिणाम लौटाते हैं, तो अगला चरण भी समानांतर में s1, s5, और s6 कहता है; अंतिम कॉल s2 के लिए। ब्लेंडर द्वारा निष्पादन आदेश निर्धारित करने के बाद, इसे नेट्टी पाइपलाइन में मैप किया जाता है। यह पाइपलाइन हैंडलर का एक अनुक्रम है जिसे प्रसंस्करण के लिए अनुरोध पारित करने की आवश्यकता होती है।
मल्टीब्लैक्सिंग इनबाउंड अनुरोध
चूंकि ब्लेंडर में वर्कफ़्लोज़ को नेट्टी पाइपलाइनों में मैप किया जाता है, इसलिए हमें आने वाले क्लाइंट अनुरोधों को उपयुक्त पाइपलाइन पर निर्देशित करना होगा। ऐसा करने के लिए, हमने एक प्रॉक्सी परत बनाई है जो मल्टीप्लेक्स और क्लाइंट अनुरोधों को निम्नलिखित नियमों के अनुसार रूट करती है:
- जब एक रिमोट थ्रिफ़ट क्लाइंट ब्लेंडर के लिए एक स्थायी कनेक्शन खोलता है, तो प्रॉक्सी लेयर स्थानीय क्लाइंट के लिए एक मैप बनाता है, जो वर्कफ़्लोज़ की सेवा देने वाले प्रत्येक स्थानीय सर्वर के लिए होता है। ध्यान दें कि ये सभी सर्वर जेवीएम वातावरण की ब्लेंडर प्रक्रिया में शुरू किए जाते हैं और ब्लेंडर प्रक्रिया शुरू होने पर बनाए जाते हैं;
- जब अनुरोध सॉकेट पर आता है, तो प्रॉक्सी परत इसे पढ़ती है, यह निर्धारित करती है कि कौन से वर्कफ़्लो का अनुरोध किया गया है और इसे संबंधित वर्कफ़्लो सर्वर पर निर्देशित करता है;
- इसी तरह, जब वर्कफ़्लो परोसने वाले स्थानीय सर्वर से प्रतिक्रिया आती है, तो प्रॉक्सी इसे पढ़ता है और रिमोट क्लाइंट के लिए प्रतिक्रिया लिखता है।
हमने उपरोक्त सभी कार्यों को अतुल्यकालिक रूप से करने के लिए इवेंट-चालित नेट्टी मॉडल का उपयोग किया, इसलिए I / O के लिए और अधिक थ्रेड्स का इंतजार नहीं करना है।
बैक-एंड अनुरोध भेजना
जैसे ही खोज अनुरोध वर्कफ़्लो की पाइपलाइन पर आता है, यह वर्कफ़्लो द्वारा निर्धारित अनुक्रम में सेवा संचालकों के अनुक्रम से गुजरता है। प्रत्येक सेवा हैंडलर इस खोज अनुरोध के लिए संबंधित बैक-एंड अनुरोध बनाता है और इसे दूरस्थ सर्वर को भेजता है। उदाहरण के लिए, एक रियल-टाइम सर्विस हैंडलर एक रियल-टाइम अनुरोध बनाता है और इसे एक या अधिक रीयल-टाइम सूचकांकों के लिए अतुल्यकालिक रूप से भेजता है। हम
ट्विटर कॉमन लाइब्रेरी का उपयोग करते हैं (जो हाल ही में ओपन सोर्स बन गया है!) कनेक्शन पूल प्रबंधन प्रदान करने के लिए, संतुलन को संतुलित करना और मृत मेजबानों की पहचान करना। I / O थ्रेड जो खोज अनुरोध को संसाधित करता है, जब सभी बैक-एंड प्रतिक्रियाओं को संसाधित किया जाता है, तो उसे मुक्त कर दिया जाता है। टाइमर थ्रेड हर कुछ मिलीसेकंड की जाँच करता है, यह देखने के लिए कि क्या बैक-एंड रिस्पॉन्स में से कोई भी रिमोट सर्वर से वापस आ गया है और यह दर्शाता है कि अनुरोध सफल रहा था या समय समाप्त हो गया था या नहीं। हम इस डेटा प्रकार को प्रबंधित करने के लिए खोज क्वेरी जीवन चक्र में एक ही वस्तु बनाए रखते हैं। सफल प्रतिक्रियाओं को वर्कफ़्लो पाइपलाइन में सर्विस हैंडलर्स द्वारा प्रोसेसिंग के लिए अगले चरण में एकत्र किया जाता है और भेजा जाता है। जब पहले चरण से सभी प्रतिक्रियाएं आती हैं, तो अतुल्यकालिक अनुरोधों का दूसरा चरण किया जाता है। यह प्रक्रिया तब तक दोहराई जाती है जब तक कि हम वर्कफ़्लो को पूरा नहीं कर लेते हैं या प्रतीक्षा समय अनुमेय सीमा से अधिक हो जाता है। जैसा कि आप देख सकते हैं, वर्कफ़्लो के निष्पादन के दौरान, एक भी धागा आई / ओ के इंतजार में बेकार नहीं है। यह हमें हमारे ब्लेंडर मशीनों पर सीपीयू का कुशलता से उपयोग करने और बड़ी संख्या में प्रतिस्पर्धी अनुरोधों को संभालने की अनुमति देता है। हम देरी पर भी बचत करते हैं, क्योंकि हम समानांतर में बैक-एंड सेवाओं के अधिकांश अनुरोधों को निष्पादित करते हैं।
ब्लेंडर की तैनाती और भविष्य के काम
जब हम अपने सिस्टम में ब्लेंडर को एकीकृत करते हैं, तो सेवा की उच्च गुणवत्ता सुनिश्चित करने के लिए, हम अपने ब्लेंडर क्लस्टर के लिए पुराने अनुरोधों को पुनर्निर्देशित करने के लिए प्रॉक्सी के रूप में पुराने रूबी-ऑन-रेल्स फ्रंट-एंड सर्वर का उपयोग करते हैं। एक प्रॉक्सी के रूप में पुराने फ्रंट-एंड सर्वर का उपयोग करना हमें उपयोगकर्ता अनुभव की अखंडता को सुनिश्चित करने की अनुमति देता है, जिससे अंतर्निहित तकनीक में महत्वपूर्ण परिवर्तन होते हैं। हमारी तैनाती के अगले चरण में, हम रूबी-ऑन-रेल्स को हमारे खोज स्टैक से पूरी तरह से हटा देंगे, उपयोगकर्ताओं को सीधे ब्लेंडर से जोड़ेंगे और संभवतः आगे भी विलंबता को कम करेंगे। "