डेटाबेस स्केलेबिलिटी पैटर्न का वर्णन करने वाले बहुत सारे लेख ऑनलाइन हैं, लेकिन वे ज्यादातर बिखरे हुए लेख हैं - केवल ऐसी तकनीकें जिन्हें बिना किसी संदर्भ के बेतरतीब ढंग से परिभाषित किया गया है। मुझे लगता है कि उन्हें चरणबद्ध तरीके से परिभाषित नहीं किया गया है, और इस बात पर चर्चा नहीं करते कि कौन सा स्केलिंग विकल्प चुनना है, कौन से स्केलिंग विकल्प अभ्यास में व्यवहार्य हैं, और क्यों।
इसलिए, मैं भविष्य के लेखों में कुछ तकनीकों पर विस्तार से चर्चा करने की योजना बना रहा हूं। शुरू करने के लिए, मुझे लगता है कि यह बेहतर है कि मैं अपने तरीके से कुछ संदर्भों के साथ चरण-दर-चरण तकनीकों पर चर्चा करूं। यह लेख एक उच्च स्तरीय लेख है - मैं यहां विस्तार से स्केलिंग तकनीकों पर चर्चा नहीं करूंगा, लेकिन एक सिंहावलोकन प्रदान करूंगा। तो चलिए शुरू करते हैं।
एक केस स्टडी
मान लें कि आपने एक स्टार्टअप बनाया है जो सस्ती कीमत पर राइड शेयरिंग की पेशकश करता है। प्रारंभ में जब आप शुरू करते हैं, तो आप एक शहर को लक्षित करते हैं और आपके प्रारंभिक विज्ञापन के बाद मुश्किल से दसियों ग्राहक होते हैं।
आप सभी ग्राहकों, यात्राओं, स्थानों, बुकिंग डेटा और ग्राहक यात्रा इतिहास को एक ही डेटाबेस में सहेजते हैं या एक भौतिक मशीन में सबसे अधिक संभावना रखते हैं। समस्याओं को हल करने के लिए कोई फैंसी कैशिंग या बड़ी डेटा पाइपलाइन नहीं है क्योंकि आपका ऐप बहुत नया है। यह इस समय आपके उपयोग के मामले के लिए एकदम सही है क्योंकि बहुत कम ग्राहक हैं और आपका सिस्टम मुश्किल से 5 मिनट में 1 ट्रिप बुक करता है, उदाहरण के लिए।
लेकिन जैसे-जैसे समय बीतता है, अधिक लोग आपके सिस्टम में साइन अप करना शुरू करते हैं क्योंकि आप बाजार में सबसे सस्ती सेवा हैं और आपके प्रचार और विज्ञापनों के लिए धन्यवाद। आप बुकिंग शुरू करते हैं, कहते हैं, प्रति मिनट 10 बुकिंग, और धीरे-धीरे संख्या बढ़कर 20, 30 बुकिंग प्रति मिनट हो जाती है।
इस समय, आप महसूस करते हैं कि सिस्टम ने खराब प्रदर्शन करना शुरू कर दिया है:एपीआई विलंबता बहुत बढ़ गई है, और कुछ लेनदेन गतिरोध या भूखे हैं और अंततः वे विफल हो जाते हैं। आपके ऐप को प्रतिक्रिया देने में अधिक समय लग रहा है, जिससे ग्राहक असंतुष्ट हो रहा है। समस्या का समाधान करने के लिए आप क्या कर सकते हैं?
पैटर्न 1 - क्वेरी ऑप्टिमाइज़ेशन और कनेक्शन पूल कार्यान्वयन:
पहला समाधान जो दिमाग में आता है वह यह है कि कैश अक्सर गैर-गतिशील डेटा जैसे बुकिंग इतिहास, भुगतान इतिहास, उपयोगकर्ता प्रोफाइल आदि का उपयोग करता है। लेकिन इस एप्लिकेशन लेयर कैशिंग के बाद, आप एपीआई की विलंबता समस्या को हल नहीं कर सकते हैं जैसे कि वर्तमान ड्राइवर का स्थान या किसी दिए गए ग्राहक के लिए निकटतम कैब या यात्रा शुरू होने के बाद एक निश्चित समय पर वर्तमान यात्रा लागत।
आप पहचानते हैं कि आपका डेटाबेस शायद अत्यधिक सामान्यीकृत है, इसलिए आप कुछ अनावश्यक कॉलम पेश करते हैं (ये कॉलम अक्सर WHERE
में दिखाई देते हैं। या JOIN ON
सामान्यीकरण के लिए अत्यधिक उपयोग की जाने वाली तालिकाओं में प्रश्नों में खंड)। यह जुड़ने वाली क्वेरी को कम करता है, एक बड़ी क्वेरी को कई छोटी क्वेरी में विभाजित करता है, और उनके परिणामों को एप्लिकेशन लेयर में जोड़ता है।
एक और समानांतर ऑप्टिमाइज़ेशन जो आप कर सकते हैं वह है डेटाबेस कनेक्शन के इर्द-गिर्द ट्वीक करना। डेटाबेस क्लाइंट लाइब्रेरी और बाहरी लाइब्रेरी लगभग सभी प्रोग्रामिंग भाषाओं में उपलब्ध हैं। आप डेटाबेस कनेक्शन को कैश करने के लिए कनेक्शन पूल लाइब्रेरी का उपयोग कर सकते हैं या डेटाबेस प्रबंधन सिस्टम में ही कनेक्शन पूल आकार को कॉन्फ़िगर कर सकते हैं।
कोई भी नेटवर्क कनेक्शन बनाना महंगा है क्योंकि इसके लिए क्लाइंट और सर्वर के बीच कुछ आगे और पीछे संचार की आवश्यकता होती है। पूलिंग कनेक्शन आपको कनेक्शन की संख्या को अनुकूलित करने में मदद कर सकता है। कनेक्शन पूल लाइब्रेरी आपको कनेक्शन को मल्टीप्लेक्स करने में मदद कर सकती है - एकाधिक एप्लिकेशन थ्रेड एक ही डेटाबेस कनेक्शन का उपयोग कर सकते हैं। मैं देखूंगा कि क्या मैं बाद में एक अलग लेख में कनेक्शन पूलिंग के बारे में विस्तार से बता सकता हूं।
आप अपने एपीआई की प्रतीक्षा अवधि को मापते हैं और संभवत:20-50% या अधिक कम विलंबता पाते हैं। इस समय यह अच्छा अनुकूलन है।
अब आपने अपने व्यवसाय को एक और शहर तक बढ़ा दिया है, अधिक ग्राहक साइन अप करें, आप धीरे-धीरे प्रति मिनट 80-100 बुकिंग करना शुरू करते हैं। आपका सिस्टम इस पैमाने को संभालने में सक्षम नहीं है। फिर से आप देखते हैं कि एपीआई विलंबता बढ़ गई है, डेटाबेस परत ने छोड़ दिया है, लेकिन इस बार, कोई क्वेरी अनुकूलन आपको कोई महत्वपूर्ण प्रदर्शन लाभ नहीं दे रहा है। आप सिस्टम मीट्रिक की जांच करते हैं, आप पाते हैं कि डिस्क स्थान लगभग भरा हुआ है, CPU 80% समय व्यस्त है, RAM बहुत जल्दी भर जाती है।
पैटर्न 2 - लंबवत स्केलिंग या स्केल अप:
सभी सिस्टम मेट्रिक्स की जांच करने के बाद, आप जानते हैं कि सिस्टम के हार्डवेयर को अपग्रेड करने के अलावा और कोई आसान समाधान नहीं है। आप अपने RAM आकार को 2 बार अपग्रेड करते हैं, डिस्क स्थान को 3 गुना या अधिक से अपग्रेड करते हैं। इसे वर्टिकल स्केलिंग या आपके सिस्टम को स्केलिंग कहा जाता है। आप अपनी मशीन को अपग्रेड करने के लिए अपनी इंफ्रास्ट्रक्चर टीम या डेवॉप्स टीम या तीसरे पक्ष के डेटा सेंटर एजेंटों को सूचित करते हैं।
लेकिन आप वर्टिकल स्केलिंग के लिए मशीन कैसे सेट अप करते हैं?
आप एक बड़ी मशीन आवंटित करते हैं। एक तरीका पुरानी मशीन से मैन्युअल रूप से डेटा माइग्रेट करना नहीं है बल्कि नई मशीन को replica
. के रूप में सेट करना है मौजूदा मशीन के लिए (primary
) - एक अस्थायी primary replica
बनाएं विन्यास। प्रतिकृति को स्वाभाविक रूप से होने दें। एक बार प्रतिकृति हो जाने के बाद, नई मशीन को प्राथमिक में बढ़ावा दें और पुरानी मशीन को ऑफ़लाइन ले जाएं। चूंकि बड़ी मशीन से सभी अनुरोधों को पूरा करने की उम्मीद की जाती है, इसलिए इस मशीन पर सभी पढ़ना/लिखना होगा।
ठंडा। आपका सिस्टम बेहतर प्रदर्शन के साथ फिर से चालू और चालू है।
आपका व्यवसाय बहुत अच्छा कर रहा है और आप 3 और शहरों में विस्तार करने का निर्णय लेते हैं - अब आप कुल 5 शहरों में काम कर रहे हैं। ट्रैफ़िक पहले की तुलना में 3 गुना अधिक है, आपसे प्रति मिनट लगभग 300 बुकिंग करने की उम्मीद है। इस लक्ष्य बुकिंग को प्राप्त करने से पहले, आप फिर से प्रदर्शन की कमी से जूझ रहे हैं, डेटाबेस इंडेक्स का आकार मेमोरी में भारी बढ़ रहा है, इसे निरंतर रखरखाव की आवश्यकता है, इंडेक्स के साथ टेबल स्कैनिंग पहले से कहीं अधिक धीमी हो रही है। आप मशीन को आगे बढ़ाने की लागत की गणना करते हैं लेकिन लागत से आश्वस्त नहीं होते हैं। अब आप क्या करते हैं?
पैटर्न 3 - कमांड क्वेरी रिस्पॉन्सिबिलिटी सेग्रीगेशन (CQRS):
आप पहचानते हैं कि बड़ी मशीन सभी read/write
. को संभालने में सक्षम नहीं है अनुरोध। साथ ही, अधिकांश मामलों में, किसी भी कंपनी को write
. पर लेनदेन क्षमता की आवश्यकता होती है लेकिन read
. पर नहीं संचालन। आप थोड़े असंगत या विलंबित read
. के साथ भी ठीक हैं संचालन और आपके व्यवसाय का इससे कोई लेना-देना नहीं है। आपको एक अवसर दिखाई देता है जहां read
. को अलग करना एक अच्छा विकल्प हो सकता है &write
संचालन भौतिक मशीन वार। यह अलग-अलग मशीनों के लिए अधिक read/write
को संभालने की गुंजाइश पैदा करेगा संचालन।
अब आप दो और बड़ी मशीनें लें और उन्हें replica
. के रूप में सेट करें वर्तमान मशीन के लिए। डेटाबेस प्रतिकृति primary
. से डेटा वितरित करने का ख्याल रखेगी मशीन से replica
मशीनें। आप सभी पढ़ी गई क्वेरी (क्वेरी (Q
.) पर नेविगेट करते हैं ) CQRS
. में ) प्रतिकृतियों के लिए — कोई भी replica
किसी भी पढ़ने के अनुरोध की सेवा कर सकते हैं, आप सभी लेखन प्रश्नों को नेविगेट करते हैं (कमांड (C
.) ) CQRS
. में ) से primary
. तक . प्रतिकृति में थोड़ा अंतराल हो सकता है, लेकिन आपके व्यावसायिक उपयोग के मामले में यह ठीक है।
अधिकांश मध्यम स्तर के स्टार्टअप, जो प्रतिदिन कुछ लाख अनुरोधों को पूरा करते हैं, प्राथमिक-प्रतिकृति सेट अप के साथ जीवित रह सकते हैं बशर्ते कि वे समय-समय पर पुराने डेटा को संग्रहीत करते हों।
अब आप 2 और शहरों का विस्तार करते हैं, आप देखते हैं कि आपका primary
सभी write
को संभालने में सक्षम नहीं है अनुरोध। कई write
अनुरोधों में विलंबता है। इसके अलावा, primary
. के बीच का अंतराल &replica
कभी-कभी ग्राहकों और ड्राइवरों को प्रभावित करते हैं - जब यात्रा समाप्त होती है, तो ग्राहक ड्राइवर को सफलतापूर्वक भुगतान करता है, लेकिन ड्राइवर भुगतान नहीं देख पाता है क्योंकि ग्राहक की गतिविधि एक write
है अनुरोध जो primary
. को जाता है , जबकि ड्राइवर की गतिविधि एक read
. है अनुरोध जो प्रतिकृतियों में से एक को जाता है। आपका समग्र सिस्टम इतना धीमा है कि ड्राइवर कम से कम आधे मिनट के लिए भुगतान नहीं देख पा रहा है - ड्राइवर और ग्राहक दोनों के लिए निराशाजनक। आप इसे कैसे हल करते हैं?
पैटर्न 4 - मल्टी प्राइमरी प्रतिकृति
आपने primary-replica
. के साथ वास्तव में अच्छा प्रदर्शन किया है कॉन्फ़िगरेशन, लेकिन अब आपको अधिक लेखन प्रदर्शन की आवश्यकता है। आप read
. पर थोड़ा समझौता करने के लिए तैयार हो सकते हैं प्रदर्शन का अनुरोध करें। लिखने के अनुरोध को replica
पर वितरित क्यों न करें भी?
एक multi-primary
. में कॉन्फ़िगरेशन, सभी मशीनें primary
दोनों के रूप में काम कर सकती हैं &replica
. आप multi-primary
के बारे में सोच सकते हैं मशीनों के एक चक्र के रूप में कहें A->B->C->D->A
. B
A
. से डेटा दोहरा सकते हैं , C
B
. से डेटा दोहरा सकते हैं , D
C
. से डेटा दोहरा सकते हैं , A
D
. से डेटा दोहरा सकते हैं . आप किसी भी नोड को डेटा लिख सकते हैं, डेटा पढ़ते समय, आप क्वेरी को सभी नोड्स पर प्रसारित कर सकते हैं, जो कोई भी उत्तर देता है वह उसे वापस कर देता है। सभी नोड्स में एक ही डेटाबेस स्कीमा, टेबल का एक ही सेट, इंडेक्स इत्यादि होगा। इसलिए आपको यह सुनिश्चित करना होगा कि id
में कोई टक्कर नहीं है। एक ही टेबल में सभी नोड्स के बीच, अन्यथा प्रसारण के दौरान, कई नोड्स एक ही id
के लिए अलग-अलग डेटा लौटाएंगे। .
आम तौर पर UUID
का उपयोग करना बेहतर होता है या GUID
आईडी के लिए इस तकनीक का एक और नुकसान है — read
क्वेरीज़ अक्षम हो सकती हैं क्योंकि इसमें ब्रॉडकास्टिंग क्वेरी और सही परिणाम प्राप्त करना शामिल है - मूल रूप से स्कैटर इकट्ठा करने का तरीका।
अब आप 5 और शहरों तक पहुंच गए हैं और आपका सिस्टम फिर से दर्द में है। आपसे प्रति सेकंड लगभग 50 अनुरोधों को संभालने की उम्मीद की जाती है। आपको भारी संख्या में समवर्ती अनुरोधों को संभालने की सख्त आवश्यकता है। आप इसे कैसे हासिल करते हैं?
पैटर्न 5 - विभाजन:
आप जानते हैं कि आपका location
डेटाबेस कुछ ऐसा है जो उच्च हो रहा है write
&read
ट्रैफ़िक। शायद write:read
अनुपात 7:3
. है . यह मौजूदा डेटाबेस पर बहुत दबाव डाल रहा है। location
तालिकाओं में कुछ प्राथमिक डेटा होते हैं जैसे longitude
, latitude
, timestamp
, driver id
, trip id
आदि। इसका उपयोगकर्ता यात्राओं, उपयोगकर्ता डेटा, भुगतान डेटा आदि से बहुत अधिक लेना-देना नहीं है। location
को अलग करने के बारे में क्या एक अलग डेटाबेस स्कीमा में टेबल? उस डेटाबेस को उचित primary-replica
के साथ अलग मशीनों में डालने के बारे में क्या? या multi-primary
विन्यास?
इसे कार्यक्षमता द्वारा डेटा का विभाजन कहा जाता है। विभिन्न डेटाबेस अलग-अलग कार्यक्षमता द्वारा वर्गीकृत डेटा को होस्ट कर सकते हैं, यदि आवश्यक हो तो परिणाम को बैक एंड लेयर में एकत्रित किया जा सकता है। इस तकनीक का उपयोग करके, आप उन कार्यात्मकताओं को अच्छी तरह से स्केल करने पर ध्यान केंद्रित कर सकते हैं जो उच्च read/write
. की मांग करते हैं अनुरोध। हालांकि बैक एंड या एप्लिकेशन लेयर को आवश्यकता पड़ने पर परिणामों में शामिल होने की जिम्मेदारी लेनी पड़ती है, जिसके परिणामस्वरूप संभवतः अधिक कोड परिवर्तन होते हैं।
अब कल्पना करें कि आपने अपने व्यवसाय का विस्तार अपने देश के कुल 20 शहरों में कर लिया है और जल्द ही ऑस्ट्रेलिया में विस्तार करने की योजना बना रहे हैं। ऐप की आपकी बढ़ती मांग के लिए तेज़ और तेज़ प्रतिक्रिया की आवश्यकता है। उपरोक्त में से कोई भी तरीका अब चरम सीमा तक आपकी मदद नहीं कर सकता है। आपको अपने सिस्टम को इस तरह से स्केल करना चाहिए कि अन्य देशों / क्षेत्रों में विस्तार करने के लिए आपको बार-बार इंजीनियरिंग या आर्किटेक्चर परिवर्तन करने की आवश्यकता न हो। आप यह कैसे करते हैं?
पैटर्न 6 - क्षैतिज स्केलिंग:
आप बहुत सारी गुगलिंग करते हैं, इस बारे में बहुत कुछ पढ़ते हैं कि अन्य कंपनियों ने इस मुद्दे को कैसे हल किया है - और इस निष्कर्ष पर पहुंचे कि आपको क्षैतिज रूप से स्केल करने की आवश्यकता है। आप कहते हैं कि 50 मशीनें आवंटित करते हैं - सभी में एक ही डेटाबेस स्कीमा होता है जिसमें बदले में तालिकाओं का एक ही सेट होता है। सभी मशीनें सिर्फ डेटा का एक हिस्सा रखती हैं।
चूंकि सभी डेटाबेस में तालिकाओं का एक ही सेट होता है, आप सिस्टम को इस तरह से डिज़ाइन कर सकते हैं कि डेटा का स्थान हो अर्थात; एक ही मशीन में सभी संबंधित डेटा भूमि। प्रत्येक मशीन की अपनी प्रतिकृतियां हो सकती हैं, प्रतिकृतियों का उपयोग विफलता पुनर्प्राप्ति में किया जा सकता है। प्रत्येक डेटाबेस को shard
. कहा जाता है . एक भौतिक मशीन में एक या एक से अधिक shards
हो सकते हैं - यह आपके डिजाइन पर निर्भर करता है कि आप कैसे चाहते हैं। आपको sharding key
के बारे में निर्णय लेना होगा इस तरह से कि एक sharding key
हमेशा एक ही मशीन को संदर्भित करता है। तो आप कल्पना कर सकते हैं कि बहुत सी मशीनें सभी संबंधित डेटा को तालिकाओं के एक ही सेट में रखती हैं, read/write
एक ही डेटाबेस मशीन में एक ही पंक्ति या संसाधन भूमि के एक ही सेट के लिए अनुरोध।
साझा करना सामान्य रूप से कठिन है - कम से कम विभिन्न कंपनियों के इंजीनियरों का कहना है कि। लेकिन जब आप लाखों या अरबों अनुरोधों को पूरा करते हैं, तो आपको इतना कठिन निर्णय लेना पड़ता है।
मैं sharding
. पर चर्चा करूंगा मेरी अगली पोस्ट में अधिक विस्तार से, इसलिए इस पोस्ट में और अधिक चर्चा करने के लिए मेरे प्रलोभन को रोकें।
अब चूंकि आपके पास शार्किंग है, इसलिए आपको विश्वास है कि आप कई देशों में पहुंच सकते हैं। आपका व्यवसाय इतना बढ़ गया है कि निवेशक आपको महाद्वीपों में व्यापार को बढ़ाने के लिए प्रेरित कर रहे हैं। आप फिर से यहाँ कुछ समस्या देखते हैं। एपीआई विलंबता फिर से। आपकी सेवा यूएसए में होस्ट की गई है और वियतनाम के लोगों को कठिन समय बुक राइड का सामना करना पड़ रहा है। क्यों? आप इसके बारे में क्या करते हैं?
पैटर्न 7 - डेटा सेंटर वाइज विभाजन:
आपका व्यवसाय अमेरिका, दक्षिण एशिया और यूरोप के कुछ देशों में बढ़ रहा है। आप अपने सर्वर पर अरबों अनुरोधों के साथ प्रतिदिन लाखों बुकिंग कर रहे हैं। बधाई - यह आपके व्यवसाय के लिए एक चरम क्षण है।
लेकिन चूंकि ऐप से अनुरोधों को इंटरनेट में सैकड़ों या हजारों सर्वरों के माध्यम से महाद्वीपों में यात्रा करना पड़ता है, इसलिए विलंबता उत्पन्न होती है। डेटा केंद्रों में ट्रैफ़िक वितरित करने के बारे में क्या? आप सिंगापुर में एक डेटा सेंटर स्थापित कर सकते हैं जो दक्षिण एशिया से सभी अनुरोधों को संभालता है, जर्मनी में डेटा सेंटर यूरोपीय देशों के सभी अनुरोधों को संभाल सकता है, और कैलिफ़ोर्निया डेटा सेंटर सभी यूएसए अनुरोधों को संभाल सकता है।
इसके अलावा आप क्रॉस डेटा सेंटर प्रतिकृति को सक्षम करते हैं जो आपदा वसूली में मदद करता है। इसलिए यदि कैलिफ़ोर्निया डेटा सेंटर सिंगापुर डेटा सेंटर की प्रतिकृति करता है, अगर कैलिफ़ोर्निया डेटा सेंटर बिजली की समस्या या प्राकृतिक आपदा के कारण दुर्घटनाग्रस्त हो जाता है, तो यूएसए के सभी अनुरोध सिंगापुर डेटा सेंटर आदि पर वापस आ सकते हैं।
यह स्केलिंग तकनीक तब उपयोगी होती है जब आपके पास पूरे देश में सेवा देने के लिए लाखों ग्राहक हों और आप किसी भी डेटा हानि को समायोजित नहीं कर सकते, आपको सिस्टम की उपलब्धता हमेशा बनाए रखनी होगी।
डेटाबेस स्केलिंग के लिए ये कुछ सामान्य चरण-दर-चरण तकनीकें हैं। हालांकि अधिकांश इंजीनियरों को इन तकनीकों को लागू करने का पर्याप्त मौका नहीं मिलता है, लेकिन समग्र रूप से ऐसी प्रणाली के बारे में व्यापक विचार प्राप्त करना बेहतर है जो भविष्य में आपको बेहतर सिस्टम और आर्किटेक्चर डिजाइनिंग करने में मदद कर सके।
अपने अगले लेखों में, मैं कुछ अवधारणाओं पर विस्तार से चर्चा करने का प्रयास करूंगा। कृपया बेझिझक इस पोस्ट के लिए उचित प्रतिक्रिया दें, यदि कोई हो।
लेख मूल रूप से लेखक के माध्यम खाते पर प्रकाशित हुआ है:https://medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522