
Mail.ru Group में, हमारे पास Tarantool है - यह Lua पर एक ऐसा एप्लिकेशन सर्वर है, जिसमें एक डेटाबेस (या इसके विपरीत?) भी है। यह तेज और ठंडा है, लेकिन एक सर्वर की क्षमता अभी भी असीमित नहीं है। वर्टिकल स्केलिंग भी रामबाण नहीं है, इसलिए टारेंटूल में क्षैतिज स्केलिंग के लिए उपकरण होते हैं - डाहर मॉड्यूल
[1] । यह आपको कई सर्वरों पर डेटा शार्प करने की अनुमति देता है, लेकिन आपको इसे कॉन्फ़िगर करने और व्यावसायिक तर्क को तेज करने के लिए इसके साथ टिंकर करना होगा।
अच्छी खबर: हमने शंकु एकत्र किया (उदाहरण के लिए
[2] ,
[3] ) और एक और रूपरेखा को देखा, जो इस समस्या के समाधान को काफी सरल करेगा।
टारेंटूल कार्ट्रिज जटिल वितरित प्रणालियों के विकास के लिए एक नई रूपरेखा है। यह आपको बुनियादी ढांचे की समस्याओं को हल करने के बजाय व्यावसायिक तर्क लिखने पर ध्यान केंद्रित करने की अनुमति देता है। कटौती के तहत, मैं आपको बताऊंगा कि यह रूपरेखा कैसे व्यवस्थित है और इसके साथ वितरित सेवाओं को कैसे लिखना है।
और क्या, वास्तव में, समस्या है?
हमारे पास एक टारेंटयुला है, वहाँ vshard है - और क्या आप चाहते हैं?
सबसे पहले, बिंदु सुविधा है। Vshard कॉन्फ़िगरेशन Lua तालिकाओं के माध्यम से कॉन्फ़िगर किया गया है। सही ढंग से काम करने के लिए कई टारेंटूल प्रक्रियाओं की वितरित प्रणाली के लिए, कॉन्फ़िगरेशन हर जगह समान होना चाहिए। कोई भी इसे मैन्युअल रूप से करना चाहता है। इसलिए, सभी प्रकार की स्क्रिप्ट, Ansible, परिनियोजन सिस्टम का उपयोग किया जाता है।
कार्ट्रिज ही vshard कॉन्फ़िगरेशन का प्रबंधन करता है; यह अपने
स्वयं के वितरित कॉन्फ़िगरेशन के आधार पर करता
है । संक्षेप में, यह एक साधारण YAML फ़ाइल है, जिसकी एक प्रति टारनटूल के प्रत्येक उदाहरण में संग्रहीत है। सरलीकरण इस तथ्य में निहित है कि फ्रेमवर्क अपने कॉन्फ़िगरेशन की निगरानी करता है और इसलिए कि यह हर जगह समान है।
दूसरे, बिंदु फिर से सुविधा में है। कॉन्फ़िगरेशन का व्यावसायिक तर्क के विकास से कोई संबंध नहीं है और केवल प्रोग्रामर को काम से विचलित करता है। जब हम किसी परियोजना की वास्तुकला पर चर्चा करते हैं, तो सबसे अधिक बार हम व्यक्तिगत घटकों और उनकी बातचीत के बारे में बात कर रहे हैं। क्लस्टर को 3 डेटा केंद्रों पर रोल करने के बारे में सोचना जल्दबाजी होगी।
हमने इन समस्याओं को बार-बार हल किया, और कुछ बिंदु पर हम अपने पूरे जीवन चक्र में आवेदन को सरल बनाने के लिए एक दृष्टिकोण विकसित करने में कामयाब रहे: निर्माण, विकास, परीक्षण, सीआई / सीडी, रखरखाव।
कार्ट्रिज प्रत्येक टारेंटूल प्रक्रिया के लिए भूमिका अवधारणा का परिचय देता है। भूमिकाएं एक अवधारणा है जो डेवलपर को कोड लिखने पर ध्यान केंद्रित करने की अनुमति देती है। परियोजना में उपलब्ध सभी भूमिकाओं को टारेंटूल के एक उदाहरण पर चलाया जा सकता है, और यह परीक्षणों के लिए पर्याप्त होगा।
टारनटूल कारतूस की मुख्य विशेषताएं:
- स्वचालित क्लस्टर ऑर्केस्ट्रेशन;
- नई भूमिकाओं के साथ अनुप्रयोग कार्यक्षमता का विस्तार;
- अनुप्रयोग विकास और परिनियोजन टेम्पलेट;
- अंतर्निहित स्वचालित शार्किंग;
- Luatest परीक्षण ढांचे के साथ एकीकरण;
- WebUI और API का उपयोग करके क्लस्टर प्रबंधन;
- पैकेजिंग और परिनियोजन उपकरण।
नमस्ते विश्व!
मैं खुद को रूपरेखा दिखाने के लिए उत्सुक हूं, तो चलिए बाद के लिए वास्तुकला के बारे में कहानी छोड़ दें, और एक साधारण से शुरू करें। टारनटूल खुद ही पहले से ही स्थापित है, जो कि किया जाना बाकी है
$ tarantoolctl rocks install cartridge-cli $ export PATH=$PWD/.rocks/bin/:$PATH
ये दोनों कमांड कमांड लाइन उपयोगिताओं को स्थापित करेंगे और आपको टेम्पलेट से अपना पहला आवेदन बनाने की अनुमति देंगे:
$ cartridge create --name myapp
और यहाँ है कि हम क्या मिलता है:
myapp/ ├── .git/ ├── .gitignore ├── app/roles/custom.lua ├── deps.sh ├── init.lua ├── myapp-scm-1.rockspec ├── test │ ├── helper │ │ ├── integration.lua │ │ └── unit.lua │ ├── helper.lua │ ├── integration/api_test.lua │ └── unit/sample_test.lua └── tmp/
यह समाप्त "हैलो, वर्ल्ड!" के साथ एक गिट रिपॉजिटरी है। आवेदन। आइए इसे तुरंत चलाने की कोशिश करें, निर्भरता को पूर्व-स्थापित करना (फ्रेमवर्क सहित):
$ tarantoolctl rocks make $ ./init.lua --http-port 8080
इसलिए, हमने भविष्य के शार्प किए गए एप्लिकेशन का एक नोड लॉन्च किया है। एक जिज्ञासु आम आदमी तुरंत वेब इंटरफेस खोल सकता है, एक नोड से एक क्लस्टर को कॉन्फ़िगर करने और परिणाम का आनंद लेने के लिए माउस का उपयोग कर सकता है, लेकिन यह आनन्दित होने के लिए बहुत जल्दी है। अब तक, एप्लिकेशन को यह नहीं पता है कि कुछ भी उपयोगी कैसे करना है, इसलिए मैं आपको बाद में तैनाती के बारे में बताऊंगा, और अब कोड लिखने का समय है।
अनुप्रयोग विकास
जरा सोचिए, हम एक ऐसी परियोजना तैयार करेंगे, जो डेटा प्राप्त करे, उसे बचाए और दिन में एक बार एक रिपोर्ट बनाए।

हम एक आरेख बनाना शुरू करते हैं, और उस पर तीन घटक रखते हैं: प्रवेश द्वार, भंडारण और अनुसूचक। हम आगे आर्किटेक्चर पर काम कर रहे हैं। चूंकि हम vshard का उपयोग संग्रहण के रूप में करते हैं, इसलिए हम इस योजना में vshard-router और vshard-storage को जोड़ते हैं। न तो गेटवे और न ही शेड्यूलर सीधे रिपॉजिटरी तक पहुंच पाएंगे, इसके लिए एक राउटर है, यह उसके लिए बनाया गया था।

यह योजना अभी भी सटीक रूप से प्रतिबिंबित नहीं करती है कि हम परियोजना में क्या बनाएंगे, क्योंकि घटक सार लगते हैं। हमें यह भी देखने की आवश्यकता है कि यह वास्तविक टारेंटूल पर कैसे पेश किया जाता है - हम अपने घटकों को प्रक्रिया से जोड़ देंगे।

अलग उदाहरणों में बनाम भार-राउटर और गेटवे को बनाए रखना बहुत कम मायने रखता है। हमें एक बार फिर नेटवर्क पर जाने की आवश्यकता क्यों है, अगर यह पहले से ही राउटर की जिम्मेदारी है? उन्हें उसी प्रक्रिया के भीतर चलना चाहिए। यही है, एक प्रक्रिया में, गेटवे और vshard.router.cfg दोनों को इनिशियलाइज़ किया जाता है, और उन्हें स्थानीय रूप से इंटरैक्ट करने दिया जाता है।
डिजाइन चरण में तीन घटकों के साथ काम करना सुविधाजनक था, लेकिन एक डेवलपर के रूप में, जब मैं कोड लिख रहा हूं, तो मैं तरनतुल के तीन उदाहरणों को लॉन्च करने के बारे में सोचना नहीं चाहता। मुझे परीक्षण चलाने और यह सत्यापित करने की आवश्यकता है कि मैंने गेटवे सही ढंग से लिखा है। या हो सकता है कि मैं अपने सहयोगियों को एक सुविधा प्रदर्शित करना चाहता हूं। मुझे तीन प्रतियों की तैनाती के साथ क्यों पीड़ित होना चाहिए? इसी से भूमिकाओं की अवधारणा का जन्म हुआ। एक भूमिका एक नियमित Loach मॉड्यूल है जिसका जीवन चक्र Cartridge द्वारा प्रबंधित किया जाता है। इस उदाहरण में, उनमें से चार हैं - प्रवेश द्वार, राउटर, भंडारण, अनुसूचक। किसी अन्य प्रोजेक्ट में, अधिक हो सकता है। सभी भूमिकाओं को एक प्रक्रिया में लॉन्च किया जा सकता है, और यह पर्याप्त होगा।

और जब मंचन या संचालन के लिए तैनात करने की बात आती है, तो हम हार्डवेयर क्षमताओं के आधार पर प्रत्येक टारेंटूल प्रक्रिया में भूमिकाओं के प्रत्येक सेट को असाइन करेंगे:

टोपोलॉजी प्रबंधन
कौन सी भूमिकाएँ कहाँ लॉन्च की गई हैं, इसकी जानकारी कहीं संग्रहीत की जानी चाहिए। और यह "कहीं न कहीं" वितरित कॉन्फ़िगरेशन है जिसका मैंने ऊपर उल्लेख किया है। इसमें सबसे महत्वपूर्ण बात क्लस्टर टोपोलॉजी है। यहां 5 टारेंटूल प्रक्रियाओं के 3 प्रतिकृति समूह हैं:

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

भूमिका जीवन
इस तरह की वास्तुकला में मौजूद रहने के लिए एक अमूर्त भूमिका के लिए, ढांचे को किसी तरह उन्हें प्रबंधित करना होगा। स्वाभाविक रूप से, नियंत्रण टारेंटूल प्रक्रिया को पुनरारंभ किए बिना होता है। भूमिकाओं के प्रबंधन के लिए 4 कॉलबैक हैं। डिस्ट्रीब्यूटेड कॉन्फ़िगरेशन में जो कुछ कहता है, उसके आधार पर कार्ट्रिज स्वयं उन्हें कॉल करेगा, जिससे कॉन्फ़िगरेशन को विशिष्ट भूमिकाओं पर लागू किया जाएगा।
function init() function validate_config() function apply_config() function stop()
प्रत्येक भूमिका में एक
init
फ़ंक्शन होता है। इसे एक बार कहा जाता है, या तो जब भूमिका सक्षम हो जाती है, या जब टारेंटूल पुनरारंभ होता है। यह वहां सुविधाजनक है, उदाहरण के लिए, box.space.create को इनिशियलाइज़ करने के लिए, या शेड्यूलर कुछ बैकग्राउंड फाइबर शुरू कर सकता है, जो कुछ निश्चित अंतराल पर काम करेगा।
init
फ़ंक्शन पर्याप्त नहीं हो सकता है। कार्ट्रिज भूमिकाओं को वितरित कॉन्फ़िगरेशन का लाभ उठाने की अनुमति देता है जो इसे टोपोलॉजी को स्टोर करने के लिए उपयोग करता है। समान कॉन्फ़िगरेशन में, हम एक नया अनुभाग घोषित कर सकते हैं और इसमें व्यावसायिक कॉन्फ़िगरेशन का एक टुकड़ा संग्रहीत कर सकते हैं। मेरे उदाहरण में, यह एक डेटा योजना हो सकती है, या शेड्यूलर की भूमिका के लिए शेड्यूल सेटिंग्स हो सकती है।
क्लस्टर हर बार वितरित कॉन्फ़िगरेशन परिवर्तन के लिए
validate_config
और
apply_config
कहता है। जब एक कॉन्फ़िगरेशन को दो-चरण प्रतिबद्ध द्वारा लागू किया जाता है, तो क्लस्टर सत्यापित करता है कि प्रत्येक भूमिका इस नए कॉन्फ़िगरेशन को स्वीकार करने के लिए तैयार है और यदि आवश्यक हो, तो उपयोगकर्ता को एक त्रुटि की रिपोर्ट करता है। जब सभी सहमत हुए कि कॉन्फ़िगरेशन सामान्य है, तो
apply_config
।
रोल्स में एक
stop
विधि भी होती है, जिसे भूमिका के महत्वपूर्ण संकेतों को साफ़ करने की आवश्यकता होती है। यदि हम कहते हैं कि इस सर्वर पर शेड्यूलर की अब कोई आवश्यकता नहीं है, तो यह उन तंतुओं को रोक सकता है, जो
init
साथ शुरू हुए थे।
भूमिकाएं एक-दूसरे के साथ बातचीत कर सकती हैं। हमें लुआ में फ़ंक्शन कॉल लिखने के लिए उपयोग किया जाता है, लेकिन ऐसा हो सकता है कि इस प्रक्रिया में हमें जो भूमिका चाहिए वह नहीं है। नेटवर्क एक्सेस की सुविधा के लिए, हम सहायक मॉड्यूल आरपीसी (रिमोट प्रोसैस कॉल) का उपयोग करते हैं, जिसे टारेंटूल में निर्मित मानक नेटबॉक्स के आधार पर बनाया गया है। यह उपयोगी हो सकता है यदि, उदाहरण के लिए, आपका गेटवे एक दिन प्रतीक्षा करने के बजाय सीधे शेड्यूलर को सीधे काम करने के लिए कहना चाहता है।
एक और महत्वपूर्ण बिंदु गलती सहिष्णुता सुनिश्चित कर रहा है। स्वास्थ्य की निगरानी के लिए कारतूस SWIM प्रोटोकॉल
[4] का उपयोग करता है। संक्षेप में, प्रक्रियाएं यूडीपी के माध्यम से एक दूसरे के साथ "अफवाहों" का आदान-प्रदान करती हैं - प्रत्येक प्रक्रिया अपने पड़ोसियों को नवीनतम समाचार बताती है, और वे जवाब देते हैं। यदि जवाब नहीं आता है, तो टारेंटूल को कुछ संदेह होने लगता है, और कुछ समय बाद वह मृत्यु का पाठ करता है और इस समाचार के बारे में सभी को बताना शुरू करता है।

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

आपको यहां सावधान रहना होगा क्योंकि बार-बार स्विच करने से प्रतिकृति के दौरान डेटा टकराव हो सकता है। यादृच्छिक पर स्वत: विफलता को चालू करें, ज़ाहिर है, इसके लायक नहीं है। आपको स्पष्ट रूप से समझने की आवश्यकता है कि क्या हो रहा है और सुनिश्चित करें कि नेता के ठीक होने के बाद प्रतिकृति नहीं टूटेगी और मुकुट उसके पास वापस आ जाएगा।
कहा गया है कि सभी से, यह लग सकता है कि भूमिकाएं माइक्रोसर्विस के समान हैं। एक मायने में, वे केवल टारेंटूल प्रक्रियाओं के भीतर मॉड्यूल के रूप में हैं। लेकिन कई बुनियादी अंतर हैं। सबसे पहले, सभी प्रोजेक्ट भूमिकाओं को एक कोड बेस में रहना चाहिए। और सभी टारेंटूल प्रक्रियाओं को एक कोड बेस से लॉन्च किया जाना चाहिए, ताकि जब हम शेड्यूलर को इनिशियलाइज़ करने की कोशिश करें तो उन पर कोई आश्चर्य न हो, लेकिन यह बस नहीं करता है। इसके अलावा, कोड के संस्करणों में अंतर की अनुमति न दें, क्योंकि ऐसी स्थिति में सिस्टम का व्यवहार भविष्यवाणी करना और डिबग करना बहुत मुश्किल है।
डॉकर के विपरीत, हम केवल एक भूमिका की "छवि" नहीं ले सकते, इसे किसी अन्य मशीन पर ले जाएं और इसे वहां चलाएं। हमारी भूमिकाएं डॉकटर कंटेनरों की तरह अलग-थलग नहीं हैं। इसके अलावा, हम एक ही उदाहरण पर दो समान भूमिका नहीं निभा सकते। भूमिका या तो वहाँ है या नहीं, एक मायने में यह सिंगलटन है। और तीसरे, पूरे प्रतिकृति समूह के भीतर भूमिकाएं समान होनी चाहिए, क्योंकि अन्यथा यह हास्यास्पद होगा - डेटा समान है, और कॉन्फ़िगरेशन अलग है।
परिनियोजन उपकरण
मैंने यह दिखाने का वादा किया कि कार्ट्रिज कैसे ऐप्स को तैनात करने में मदद करता है। दूसरों के लिए जीवन आसान बनाने के लिए, फ्रेमवर्क RPM संकुल पैक करता है:
$ cartridge pack rpm myapp # ./myapp-0.1.0-1.rpm $ sudo yum install ./myapp-0.1.0-1.rpm
इंस्टॉल किए गए पैकेज में आपकी ज़रूरत की लगभग हर चीज़ होती है: एप्लिकेशन और इंस्टॉल किए गए लॉच निर्भरता दोनों। टारेंटूल भी RPM पैकेज निर्भरता के रूप में सर्वर पर आएगा, और हमारी सेवा लॉन्च करने के लिए तैयार है। यह सिस्टमड के माध्यम से किया जाता है, लेकिन पहले आपको थोड़ा कॉन्फ़िगरेशन लिखने की आवश्यकता है। कम से कम, प्रत्येक प्रक्रिया का यूआरआई निर्दिष्ट करें। उदाहरण के लिए तीन पर्याप्त है।
$ sudo tee /etc/tarantool/conf.d/demo.yml <<CONFIG myapp.router: {"advertise_uri": "localhost:3301", "http_port": 8080} myapp.storage_A: {"advertise_uri": "localhost:3302", "http_enabled": False} myapp.storage_B: {"advertise_uri": "localhost:3303", "http_enabled": False} CONFIG
यहां एक दिलचस्प बारीकियां है। केवल बाइनरी प्रोटोकॉल पोर्ट को निर्दिष्ट करने के बजाय, हम होस्टनाम सहित पूरी प्रक्रिया का सार्वजनिक पता निर्दिष्ट करते हैं। यह आवश्यक है ताकि क्लस्टर नोड्स को पता हो कि एक दूसरे से कैसे जुड़ा जाए। यह एक बुरा विचार है कि एड्रेस 0.0 का प्रयोग 0.0.0.0 को advert_uri के रूप में करें, यह एक बाहरी आईपी एड्रेस होना चाहिए, न कि बाइंड सॉकेट। इसके बिना, कुछ भी काम नहीं करेगा, इसलिए कारतूस केवल नोड को गलत विज्ञापन_ के साथ शुरू नहीं होने देगा।
अब जब कॉन्फ़िगरेशन तैयार हो गया है, तो आप प्रक्रियाओं को शुरू कर सकते हैं। चूंकि एक नियमित सिस्टमड यूनिट एक से अधिक प्रक्रिया शुरू करने की अनुमति नहीं देती है, कार्ट्रिज पर एप्लिकेशन तथाकथित स्थापित करते हैं इस तरह से काम करने वाली तात्कालिक इकाइयाँ:
$ sudo systemctl start myapp@router $ sudo systemctl start myapp@storage_A $ sudo systemctl start myapp@storage_B
कॉन्फ़िगरेशन में, हमने HTTP पोर्ट निर्दिष्ट किया है, जिस पर कार्ट्रिज वेब इंटरफ़ेस - 8080 परोसता है। आइए हम इस पर चलते हैं और देखते हैं:

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

परिणाम
और परिणाम क्या हैं? कोशिश करें, उपयोग करें, प्रतिक्रिया छोड़ें, जीथब पर टिकट शुरू करें।
संदर्भ
[1]
टारेंटूल »२.२» संदर्भ »रॉक्स संदर्भ» मॉड्यूल बनाम[२]
हमने टारनटूल पर आधारित अल्फ़ा-बैंक के निवेश व्यवसाय के मूल को कैसे लागू किया[३]
नेक्स्ट-जेनेरेशन बिलिंग आर्किटेक्चर: ट्रेंटिशनिंग टू टारेंटूल[४]
SWIM - क्लस्टर बिल्डिंग प्रोटोकॉल[५]
गिटहब - टारेंटूल / कार्ट्रिज-क्लाई[६]
गिटहब - टारनटूल / कारतूस