जब आप किसी युवा प्रोजेक्ट पर काम कर रहे होते हैं तो आप लगातार ऐसे निर्णय ले रहे होते हैं जो बाद में इसे स्केल करना आसान या कठिन बना देगा। कभी-कभी अल्पकालिक लाभ चुनना अच्छा होता है, थोड़ा तकनीकी ऋण अर्जित करने के लिए ताकि आप तेजी से जहाज कर सकें। लेकिन दूसरी बार हम तकनीकी कर्ज उठाते हैं क्योंकि हमें नहीं पता था कि कोई विकल्प है।
मैं ऐसा इसलिए कह सकता हूं क्योंकि यहां हनीबैगर में, हमने कुछ ऐसे काम किए, जिससे हम पर जीवन पहले से कहीं अधिक कठिन हो गया। अगर हम कुछ प्रमुख बिंदुओं को समझ लेते तो स्केलिंग बहुत कम दर्दनाक होती।
UUIDs का उपयोग करें
जब आप "प्राथमिक कुंजी" कहते हैं, तो हम में से अधिकांश एक ऑटो-इंक्रीमेंटिंग नंबर के बारे में सोचते हैं। यह छोटी प्रणालियों के लिए अच्छी तरह से काम करता है, लेकिन जैसे ही आप बड़े होते हैं यह एक बड़ी समस्या पेश करता है।
किसी भी समय केवल एक डेटाबेस सर्वर प्राथमिक कुंजी उत्पन्न कर सकता है। इसका मतलब है सभी राइट्स को एक ही सर्वर से गुजरना पड़ता है। यह बुरी खबर है अगर आप प्रति सेकंड हजारों लिखना चाहते हैं।
प्राथमिक कुंजी के रूप में यूयूआईडी का उपयोग इस समस्या को दूर करता है। यदि आप उनसे परिचित नहीं हैं, तो यूयूआईडी अद्वितीय पहचानकर्ता हैं जो इस तरह दिखते हैं:123e4567-e89b-12d3-a456-426655440000
.
यहां बताया गया है कि विकिपीडिया उनका वर्णन कैसे करता है:
<ब्लॉककोट>जब मानक विधियों के अनुसार उत्पन्न किया जाता है, तो यूयूआईडी व्यावहारिक उद्देश्यों के लिए अद्वितीय होते हैं, बिना केंद्रीय पंजीकरण प्राधिकरण या उन्हें उत्पन्न करने वाली पार्टियों के बीच समन्वय की आवश्यकता के बिना। यूयूआईडी के डुप्लीकेट होने की संभावना शून्य नहीं है, लेकिन शून्य के इतने करीब है कि नगण्य हो।
इस प्रकार, कोई भी एक यूयूआईडी बना सकता है और इसका उपयोग लगभग निश्चितता के साथ किसी चीज़ की पहचान करने के लिए कर सकता है कि पहचानकर्ता किसी अन्य चीज़ की पहचान करने के लिए पहले से ही बनाए गए एक को डुप्लिकेट नहीं करता है, और भविष्य में डुप्लिकेट नहीं किया जाएगा। स्वतंत्र पक्षों द्वारा यूयूआईडी के साथ लेबल की गई जानकारी को बाद में एकल डेटाबेस में जोड़ा जा सकता है, या पहचानकर्ताओं के बीच संघर्ष को हल करने की आवश्यकता के बिना उसी चैनल पर प्रसारित किया जा सकता है।
जब आप यूयूआईडी को प्राथमिक कुंजी के रूप में उपयोग करते हैं, तो सभी लिखने के लिए अब एक डेटाबेस से गुजरना नहीं पड़ता है। इसके बजाय आप उन्हें कई सर्वरों में फैला सकते हैं।
इसके अलावा वे आपको पहले . रिकॉर्ड की आईडी जेनरेट करने जैसी चीज़ें करने की सुविधा देते हैं यह डेटाबेस में सहेजा गया है। यह उपयोगी हो सकता है यदि आप रिकॉर्ड को कैशे या खोज सर्वर पर भेजना चाहते हैं, लेकिन डेटाबेस लेनदेन के पूरा होने की प्रतीक्षा नहीं करना चाहते हैं।
रेल ऐप्स में डिफ़ॉल्ट रूप से यूयूआईडी को सक्षम करना आसान है। बस कॉन्फ़िग फ़ाइल संपादित करें:
# config/application.rb
config.active_record.primary_key = :uuid
आप रेल माइग्रेशन के साथ एक व्यक्तिगत तालिका के लिए यूयूआईडी का उपयोग कर सकते हैं:
create_table :users, id: :uuid do |t|
t.string :name
end
यह एक सरल कॉन्फ़िगरेशन विकल्प है, यदि आप विकास शुरू करते समय इसे सक्षम करते हैं, तो जब आप स्केल करने का प्रयास करेंगे तो आपको परेशानी की दुनिया से बचाएगा। एक अतिरिक्त बोनस के रूप में, यह बॉट्स और बुरे अभिनेताओं के लिए आपके निजी URL का अनुमान लगाना कठिन बना देगा।
गणना और काउंटर
एक बार जब आप देखना शुरू करते हैं, तो गिनती और काउंटर हर जगह होते हैं। आपका ईमेल क्लाइंट अपठित ईमेल की संख्या प्रदर्शित करता है। ब्लॉग में पेजिनेशन फ़ुटर होता है जो पेजों की संख्या की गणना करने के लिए पोस्ट की कुल संख्या का उपयोग करता है।
काउंटरों में स्केलिंग की दो समस्याएं हैं:
- डेटाबेस क्वेरीज़ जैसे
select count(*) from users
स्वाभाविक रूप से धीमे हैं। वे सचमुच अपने परिणाम उत्पन्न करने के लिए रिकॉर्डसेट में प्रत्येक रिकॉर्ड के माध्यम से लूप करते हैं। यदि आपके पास एक मिलियन रिकॉर्ड हैं, तो इसमें कुछ समय लगेगा। - "काउंटर कैश" का उपयोग करके काउंटरों को गति देने के प्रयास काम करते हैं, लेकिन वे कई डेटाबेस सर्वरों में लिखने की आपकी क्षमता को सीमित कर देते हैं।
सबसे आसान उपाय यह है कि जहां भी संभव हो काउंटरों का उपयोग करने से बचें। जब आप प्रारंभिक डिज़ाइन कर रहे हों तो यह बहुत आसान होता है।
उदाहरण के लिए, आप गणना के बजाय दिनांक-सीमा के आधार पर पृष्ठ चुनना चुन सकते हैं। हो सकता है कि आप हल्का-सा उपयोगी आँकड़ा न दिखाने का चुनाव करें जो बाद में उत्पन्न करने के लिए नारकीय होगा। तुम्हें नया तरीका मिल गया है।
एक्सपायरिंग और वेयरहाउसिंग डेटा
आपके पास RAM, CPU और डिस्क IO की मात्रा को देखते हुए एक पोस्टग्रेज टेबल में आप कितना डेटा स्टोर कर सकते हैं, इसकी एक ऊपरी सीमा है। इसका मतलब है कि एक बिंदु आएगा जब आपको अपने मुख्य तालिकाओं से पुराने डेटा को स्थानांतरित करने की आवश्यकता होगी।
आइए एक साधारण मामले को देखें। आप कुछ गीगाबाइट बड़े डेटाबेस में एक वर्ष से अधिक पुराने रिकॉर्ड हटाना चाहते हैं।
यदि आपने पहले कभी इस समस्या का समाधान नहीं किया है, तो आप कुछ ऐसा करने के लिए ललचा सकते हैं:
MyRecords.where("created_at < ?", 1.year.ago).destroy
समस्या यह है कि इस क्वेरी को चलने में कुछ दिन या सप्ताह लगेंगे। आपका डेटाबेस अभी बहुत बड़ा है।
यह एक विशेष रूप से दर्दनाक समस्या है, क्योंकि अक्सर आपको पता ही नहीं चलता कि आपके पास यह है जब तक कि बहुत देर हो चुकी न हो। शायद ही कोई डेटा शुद्ध करने की रणनीतियों के बारे में सोचता है जब उनकी कंपनी युवा होती है और उनके डेटाबेस में 1,000 रिकॉर्ड होते हैं।
यदि आप आगे की योजना बनाने का प्रबंधन करते हैं, तो एक आसान समाधान है। बस अपनी टेबल विभाजित करें। अपना सारा डेटा my_records
. पर लिखने के बजाय आप इस सप्ताह का डेटा my_records_1
. पर लिखें और अगले सप्ताह का डेटा my_records_2
. को . जब पिछले सप्ताह को हटाने का समय हो, तो बस drop table my_records_1
. हटाने के विपरीत, यह क्वेरी बहुत जल्दी पूरी होती है।
दिनांक के अलावा अन्य क्षेत्रों द्वारा भी विभाजन करना संभव है। आपके उपयोग-मामले के लिए जो कुछ भी समझ में आता है।
यहां तक कि pg_partman नाम का एक पोस्टग्रेज एक्सटेंशन भी है जो सभी विवरणों का ध्यान रखता है और आपको अपने कोड की एक पंक्ति को बदले बिना अपने डेटाबेस को विभाजित करने की अनुमति देता है। या, यदि आप रूबी में विभाजन को प्रबंधित करना पसंद करते हैं, तो एक आसान रत्न है जिसे विभाजन योग्य कहा जाता है
विभाजन शब्द
अगली बार जब आप खुद को नए सिरे से प्रोजेक्ट बनाते हुए देखें, तो मैं आपको स्केलिंग के बारे में सोचने के लिए कुछ समय निकालने के लिए प्रोत्साहित करूंगा। इसके प्रति आसक्त न हों। एचएएमएल या ईआरबी का उपयोग करने के बारे में चिंता करने में दिन न बिताएं। लेकिन अपने आप से पूछें कि क्या कोई आसान जीत नहीं है जिसे आप केवल आगे की योजना बनाकर उठा सकते हैं।