2.1 N बार शार्ड और स्लो डाउन कैसे करें?

आप इस तरह ठीक N बार शार्द और धीमा कर सकते हैं:

  • डॉक्स00... डॉक्स15 अनुरोध क्रमिक रूप से भेजें , समानांतर में नहीं।
  • सरल प्रश्नों में, कुंजी द्वारा चयन न करें , जहां कुछ = 234।

इस मामले में, क्रमबद्ध भाग (सीरियल) 1% या 5% नहीं, बल्कि आधुनिक डेटाबेस में लगभग 20% लेता है। यदि आप एक बेतहाशा कुशल बाइनरी प्रोटोकॉल का उपयोग करके डेटाबेस तक पहुँचते हैं या इसे डायनेमिक लाइब्रेरी के रूप में पायथन स्क्रिप्ट में लिंक करते हैं, तो आप क्रमबद्ध भाग का 50% भी प्राप्त कर सकते हैं।

एक साधारण अनुरोध के प्रसंस्करण समय के बाकी समय अनुरोध को पार्स करने, योजना तैयार करने आदि के गैर-समानांतर कार्यों द्वारा कब्जा कर लिया जाएगा। यानी रिकॉर्ड न पढ़ना धीमा हो जाता है।

यदि हम डेटा को 16 तालिकाओं में विभाजित करते हैं और क्रमिक रूप से चलाते हैं, जैसा कि PHP प्रोग्रामिंग भाषा में प्रथागत है, उदाहरण के लिए, (यह अतुल्यकालिक प्रक्रियाओं को लॉन्च करने में बहुत अच्छा नहीं है), तो हमें 16 गुना मंदी मिलेगी। और, शायद, इससे भी ज्यादा, क्योंकि नेटवर्क राउंड-ट्रिप भी जोड़े जाएंगे।

शार्पिंग करते समय अचानक प्रोग्रामिंग लैंग्वेज का चुनाव महत्वपूर्ण हो जाता है।

प्रोग्रामिंग भाषा की पसंद के बारे में याद रखें, क्योंकि यदि आप डेटाबेस (या खोज सर्वर) को क्रमिक रूप से प्रश्न भेजते हैं, तो त्वरण कहाँ से आता है? बल्कि मंदी रहेगी।

2.2 अर्ध-स्वचालित के बारे में

कई जगहों पर, सूचना प्रौद्योगिकी का परिष्कार कालातीत आतंक को प्रेरित करता है। उदाहरण के लिए, बॉक्स से बाहर MySQL में निश्चित रूप से निश्चित संस्करणों के लिए शार्डिंग का कार्यान्वयन नहीं था, हालाँकि, युद्ध में उपयोग किए जाने वाले डेटाबेस के आकार अशोभनीय मूल्यों तक बढ़ते हैं।

व्यक्तिगत डीबीए के सामने पीड़ित मानवता को वर्षों से सताया गया है और कुछ भी नहीं के आधार पर कई खराब शार्डिंग समाधान लिखता है। उसके बाद, ProxySQL (MariaDB/Spider, PG/pg_shard/Citus, ...) नामक एक या कम सभ्य शार्डिंग समाधान लिखा जाता है। यह इस धब्बा का एक प्रसिद्ध उदाहरण है।

ProxySQL समग्र रूप से, खुले स्रोत के लिए, रूटिंग और अधिक के लिए एक पूर्ण उद्यम-वर्ग समाधान है। लेकिन हल किए जाने वाले कार्यों में से एक डेटाबेस के लिए शार्डिंग है, जो अपने आप में मानवीय तरीके से शार्प नहीं हो सकता है। आप देखते हैं, कोई "शार्क = 16" स्विच नहीं है, आपको या तो एप्लिकेशन में प्रत्येक अनुरोध को फिर से लिखना होगा, और उनमें से बहुत से स्थान हैं, या एप्लिकेशन और डेटाबेस के बीच कुछ मध्यवर्ती परत डालते हैं जो दिखता है: "हम्म ... दस्तावेज़ों से * चुनें? हां, इसे 16 छोटे SELECT * FROM server1.document1, SELECT * FROM server2.document2 में विभाजित किया जाना चाहिए - इस सर्वर को इस तरह के लॉगिन / पासवर्ड के साथ, इस एक को दूसरे के साथ। अगर किसी ने जवाब नहीं दिया, तो...", आदि। बिल्कुल यह मध्यवर्ती धब्बों द्वारा किया जा सकता है। वे सभी डेटाबेस की तुलना में थोड़े कम हैं। जहाँ तक मैं समझता हूँ PostgreSQL के लिए,

प्रत्येक विशिष्ट पैच को कॉन्फ़िगर करना एक अलग विशाल विषय है जो एक रिपोर्ट में फिट नहीं होगा, इसलिए हम केवल मूल अवधारणाओं पर चर्चा करेंगे। आइए बज़ के सिद्धांत के बारे में थोड़ी बात करें।

2.3 पूर्ण पूर्ण स्वचालन?

इस अक्षर F() में शार्डिंग के मामले में उच्च होने का पूरा सिद्धांत , मूल सिद्धांत हमेशा मोटे तौर पर समान होता है: shard_id = F(object).

शेरिंग - यह सब क्या है? हमारे पास 2 बिलियन रिकॉर्ड (या 64) हैं। हम उन्हें कई टुकड़ों में तोड़ना चाहते हैं। एक अप्रत्याशित प्रश्न उठता है - कैसे? मेरे लिए उपलब्ध 16 सर्वरों पर मुझे अपने 2 बिलियन रिकॉर्ड (या 64) को किस सिद्धांत से बिखेरना चाहिए?

हमारे भीतर छिपे गणितज्ञ को यह सुझाव देना चाहिए कि अंत में हमेशा कुछ जादुई कार्य होता है, जो प्रत्येक दस्तावेज़ (वस्तु, रेखा, आदि) के लिए यह निर्धारित करेगा कि इसे किस टुकड़े में रखा जाए।

गणित में गहराई से जाने पर, यह फ़ंक्शन हमेशा न केवल वस्तु (स्वयं पंक्ति) पर निर्भर करता है, बल्कि बाहरी सेटिंग्स जैसे कि शार्क की कुल संख्या पर भी निर्भर करता है। एक फ़ंक्शन जो प्रत्येक ऑब्जेक्ट के लिए यह बताता है कि इसे कहां रखा जाए, सिस्टम में सर्वर से अधिक मूल्य नहीं लौटा सकता है। और कार्य थोड़े अलग हैं:

shard_func = F1(object); 
shard_id = F2(shard_func, ...); 
shard_id = F2(F1(object), current_num_shards, ...). 

लेकिन आगे हम अलग-अलग कार्यों के इन विकलों में नहीं खोदेंगे, हम सिर्फ इस बारे में बात करेंगे कि एफ () क्या जादू कार्य करता है।

2.4 एफ () क्या हैं?

वे कई अलग-अलग और कई अलग-अलग कार्यान्वयन तंत्रों के साथ आ सकते हैं। नमूना सारांश:

  • एफ = रैंड ()% nums_shards
  • F = somehash(object.id) % num_shards
  • एफ = वस्तु दिनांक% num_shards
  • F = object.user_id% num_shards
  • ...
  • F = shard_table [ somehash() |… object.date |… ]

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

एक पुनरुत्पादित या यहां तक ​​​​कि सुसंगत हैश फ़ंक्शन, या कुछ विशेषताओं द्वारा शार्ड द्वारा शार्द करने के लिए कुछ अधिक बुद्धिमान तरीके हैं। आइए प्रत्येक विधि के बारे में जानें।

एफ = रैंड ()

इधर-उधर बिखरना बहुत सही तरीका नहीं है। एक समस्या: हमने अपने 2 अरब रिकॉर्ड बेतरतीब ढंग से एक हजार सर्वर पर बिखेर दिए, और हम नहीं जानते कि रिकॉर्ड कहां है। हमें user_1 को बाहर निकालने की आवश्यकता है, लेकिन हम नहीं जानते कि यह कहाँ है। हम एक हजार सर्वरों पर जाते हैं और सब कुछ छाँटते हैं - किसी तरह यह अक्षम है।

एफ = सोमेश ()

आइए उपयोगकर्ताओं को एक वयस्क तरीके से तितर-बितर करें: user_id से प्रतिलिपि प्रस्तुत करने योग्य हैश फ़ंक्शन की गणना करें, शेष विभाजन को सर्वरों की संख्या से लें, और तुरंत वांछित सर्वर से संपर्क करें।

हम यह क्यों कर रहे हैं? और फिर, हमारे पास एक उच्च भार है और कुछ भी एक सर्वर में फिट नहीं होता है। यदि यह फिट होता, तो जीवन इतना सरल होता।

बढ़िया, स्थिति में पहले से सुधार हुआ है, एक रिकॉर्ड प्राप्त करने के लिए, हम पहले से एक ज्ञात सर्वर पर जाते हैं। लेकिन अगर हमारे पास चाबियों की एक श्रृंखला है, तो इस पूरी रेंज में हमें चाबियों के सभी मूल्यों के माध्यम से जाने की जरूरत है और सीमा में या तो उतने ही शार्ड्स तक जाएं जितने कि हमारे पास रेंज में चाबियां हैं, या यहां तक ​​​​कि प्रत्येक सर्वर। बेशक, स्थिति में सुधार हुआ है, लेकिन सभी अनुरोधों के लिए नहीं। कुछ प्रश्न प्रभावित हुए हैं।

प्राकृतिक शार्डिंग (F = object.date % num_shards)

कभी-कभी, यानी अक्सर, 95% ट्रैफ़िक और 95% लोड ऐसे अनुरोध होते हैं जिनमें किसी प्रकार की प्राकृतिक शार्डिंग होती है। उदाहरण के लिए, 95% सशर्त सामाजिक-विश्लेषणात्मक क्वेरी केवल पिछले 1 दिन, 3 दिन, 7 दिनों के डेटा को प्रभावित करती हैं और शेष 5% पिछले कुछ वर्षों को संदर्भित करती हैं। लेकिन 95% अनुरोध इस प्रकार स्वाभाविक रूप से तिथि के अनुसार तेज हो जाते हैं, सिस्टम उपयोगकर्ताओं की रुचि पिछले कुछ दिनों पर केंद्रित है।

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

जीवन में सुधार हो रहा है - अब हम न केवल किसी विशेष वस्तु का स्थान जानते हैं, बल्कि हम सीमा के बारे में भी जानते हैं। यदि हमसे तारीखों की एक सीमा के लिए नहीं, बल्कि अन्य स्तंभों की एक श्रृंखला के लिए कहा जाता है, तो निश्चित रूप से, हमें सभी टुकड़ों से गुजरना होगा। लेकिन खेल के नियमों के अनुसार, हमारे पास ऐसे अनुरोध केवल 5% हैं।

ऐसा लगता है कि हम सब कुछ के लिए एक आदर्श समाधान लेकर आए हैं, लेकिन दो समस्याएं हैं:

  • यह समाधान एक विशिष्ट मामले के लिए तैयार किया गया है, जब 95% अनुरोधों में केवल अंतिम सप्ताह शामिल होता है।
  • चूँकि 95% अनुरोध पिछले सप्ताह तक पहुँचते हैं, वे सभी एक शार्ड पर गिरेंगे जो पिछले सप्ताह इस परोसता है। यह टुकड़ा पिघल जाएगा, जबकि अन्य सभी इस समय के दौरान निष्क्रिय रहेंगे। उसी समय, आप उन्हें फेंक नहीं सकते, अभिलेखीय डेटा भी संग्रहीत किया जाना चाहिए।

यह कहने के लिए नहीं कि यह एक खराब शार्डिंग स्कीम है - हम हॉट डेटा को काट देते हैं, फिर भी, हॉटेस्ट शार्ड के साथ कुछ करने की आवश्यकता है।

समस्या को हरकतों, छलांग और पुल्टिस द्वारा हल किया जाता है, अर्थात, जलते हुए वर्तमान दिन के लिए प्रतिकृतियों की संख्या में वृद्धि, फिर धीरे-धीरे प्रतिकृतियों की संख्या में कमी जब यह दिन अतीत बन जाता है और संग्रह में चला जाता है। कोई आदर्श समाधान नहीं है जिसे "आपको गलत तरीके से जादू हैश फ़ंक्शन के साथ क्लस्टर पर डेटा फैलाने की आवश्यकता है"।

2.5 भुगतान की जाने वाली कीमत

औपचारिक रूप से, अब हम जानते हैं कि हम "सब कुछ" जानते हैं। सच है, हम एक विशाल सिरदर्द और दो छोटे सिरदर्द नहीं जानते हैं।

1. साधारण दर्द: बुरी तरह से धब्बा

यह पाठ्यपुस्तक से एक उदाहरण है, जो लगभग युद्ध में कभी नहीं होता, लेकिन अचानक होता है।

  • एक तारीख के साथ एक उदाहरण के रूप में, केवल एक तारीख के बिना!
  • अनजाने में असमान (बोधगम्य) वितरण।

उन्होंने शार्डिंग मैकेनिज्म को चुना, और/या डेटा बदल गया, और निश्चित रूप से, पीएम ने आवश्यकताओं को व्यक्त नहीं किया (हमारे पास कोड में त्रुटियां नहीं हैं, पीएम हमेशा आवश्यकताओं की रिपोर्ट नहीं करता है), और वितरण राक्षसी रूप से असमान हो गया। यानी कसौटी से चूक गए।

पकड़ने के लिए, आपको शार्क के आकार को देखने की जरूरत है। हम निश्चित रूप से समस्या को उस समय देखेंगे जब हमारा एक टुकड़ा या तो ज़्यादा गरम हो जाएगा या दूसरों की तुलना में 100 गुना बड़ा हो जाएगा। आप इसे केवल कुंजी या शार्डिंग फ़ंक्शन को बदलकर ठीक कर सकते हैं।

यह एक साधारण समस्या है, ईमानदारी से कहूं तो मुझे नहीं लगता कि सौ में से कम से कम एक व्यक्ति को जीवन में यह समस्या आएगी, लेकिन अचानक यह कम से कम किसी की मदद करेगा।

2. "अजेय" दर्द: एकत्रीकरण, शामिल हों

चयन कैसे करें जो एक तालिका से एक अरब रिकॉर्ड के लिए एक तालिका से एक अरब रिकॉर्ड में शामिल हो?

  • कैसे "जल्दी से" गणना करने के लिए ... आआ और बब्ब के बीच रैंडकोल कहाँ है?
  • कैसे "स्मार्टली" करें...

संक्षिप्त उत्तर: कोई रास्ता नहीं, पीड़ित!

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

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

यह तीन दिनों के लिए व्याख्यान का एक अलग कोर्स है, तो चलिए अंतिम नारकीय पीड़ा और इससे निपटने के लिए अलग-अलग एल्गोरिदम पर चलते हैं।

2.6। जटिल / लंबा दर्द: पुनर्वितरण

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

इससे कोई फर्क नहीं पड़ता कि आप कितने क्लस्टर कॉन्फ़िगर करते हैं, फिर भी आपको रीशर्ड करने की आवश्यकता है।

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

यह अच्छा है अगर हमारे पास दो की अच्छी शक्तियाँ हैं: 16 सर्वर शार्द थे, अब यह 32 है। यह अधिक मजेदार है यदि यह 17 था, यह 23 है - दो समान रूप से अभाज्य संख्याएँ। डेटाबेस इसे कैसे करते हैं, हो सकता है कि उनके अंदर किसी तरह का जादू हो?

सही उत्तर है: नहीं, अंदर कोई जादू नहीं है, उनके अंदर नरक है।

अगला, हम विचार करेंगे कि "हाथ से" क्या किया जा सकता है, शायद हम "एक स्वचालित मशीन के रूप में" समझेंगे।

माथे पर # 1। सब कुछ स्थानांतरित करें

सभी वस्तुओं के लिए, हम NewF (ऑब्जेक्ट) पर विचार करते हैं, एक नए शार्ड में शिफ्ट होते हैं।

NewF()=OldF() मिलान की संभावना कम है।

आइए लगभग सब कुछ कवर करें।

ओह।

मुझे उम्मीद है कि ऐसा कोई नरक नहीं है जो सभी 2 बिलियन रिकॉर्ड को पुराने टुकड़ों से नए में स्थानांतरित कर दे। भोला दृष्टिकोण समझ में आता है: 17 मशीनें थीं, 6 मशीनों को क्लस्टर में जोड़ा गया था, 2 बिलियन रिकॉर्ड छांटे गए थे, उन्हें 17 मशीनों से 23 मशीनों में स्थानांतरित किया गया था। हर 10 साल में एक बार, आप शायद इसे भी कर सकते हैं। लेकिन कुल मिलाकर यह एक खराब कदम है।

माथे पर #2. आधा स्थानांतरित करें

अगला भोला सुधार - आइए इस तरह की मूर्खतापूर्ण योजना को छोड़ दें - 17 कारों को 23 में फिर से शुरू करने से रोकेंगे, और हम हमेशा 16 कारों को 32 कारों में बदल देंगे! फिर, सिद्धांत के अनुसार, हमें ठीक आधे डेटा को स्थानांतरित करना होगा, और व्यवहार में हम ऐसा भी कर सकते हैं।

सभी वस्तुओं के लिए, हम NewF (ऑब्जेक्ट) पर विचार करते हैं, एक नए शार्ड में शिफ्ट होते हैं।

यह सख्ती से 2^एन था, अब यह सख्ती से 2^(एन+1) शार्क है।

NewF()=OldF() मिलान की संभावना 0.5 है।

आइए लगभग 50% डेटा ट्रांसफर करें।

इष्टतम, लेकिन केवल दो की शक्तियों के लिए काम करता है।

सिद्धांत रूप में, कारों की संख्या के मामले में दो की शक्ति के बंधन को छोड़कर, सब कुछ ठीक है। यह भोला दृष्टिकोण, विचित्र रूप से पर्याप्त, काम कर सकता है।

कृपया ध्यान दें कि इस मामले में दो की शक्तियों द्वारा क्लस्टर का अतिरिक्त विभाजन भी इष्टतम है। किसी भी मामले में, 16 मशीनों को 16 के क्लस्टर में जोड़कर, हम डेटा के आधे हिस्से को शिफ्ट करने के लिए बाध्य हैं - ठीक आधा और शिफ्ट।

ठीक है, लेकिन क्या मानव जाति ने वास्तव में किसी और चीज का आविष्कार नहीं किया है - प्रश्न एक जिज्ञासु मन से उठता है।

अधिक मज़ा #3। लगातार हैशिंग

बेशक, यहां संगत हैशिंग के बारे में एक चक्र के साथ एक तस्वीर की आवश्यकता है।

यदि आप "लगातार हैशिंग" गूगल करते हैं, तो निश्चित रूप से एक सर्कल निकलेगा, सभी परिणाम मंडलियों से आबाद हैं।

आइडिया: चलो एक सर्कल पर शार्प आइडेंटिफायर (हैश) बनाते हैं, और शीर्ष पर हैशेड सर्वर आइडेंटिफायर को चिह्नित करते हैं। जब आपको एक सर्वर जोड़ने की आवश्यकता होती है, तो हम सर्कल पर एक नया बिंदु डालते हैं, और जो इसके करीब निकला (और जो इसके करीब निकला), हम स्थानांतरित करते हैं।

एक शार्ड जोड़ते समय: हम सब कुछ नहीं देखते हैं, लेकिन केवल 2 "पड़ोसियों" को देखते हैं, हम औसतन 1/n शिफ्ट करते हैं।

शार्ड को हटाते समय: हम केवल हटाए जा रहे शार्ड को देखते हैं, हम केवल इसे शिफ्ट करते हैं। इष्टतम प्रकार।

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

यह समस्या वर्चुअल नोड की अंतिम पंक्ति द्वारा हल की जाती है। सर्कल पर प्रत्येक नोड, प्रत्येक सर्वर को एक से अधिक बिंदुओं द्वारा इंगित किया जाता है। सर्वर, शार्ड आदि को जोड़कर हम कुछ बिंदु जोड़ रहे हैं। हर बार जब हम कुछ हटाते हैं, तो हम तदनुसार कुछ बिंदुओं को हटा देते हैं और डेटा के एक छोटे हिस्से को स्थानांतरित कर देते हैं।

मैं इस स्थान के बारे में हलकों के साथ बात कर रहा हूं, क्योंकि, उदाहरण के लिए, कैसेंड्रा के अंदर ऐसी योजना है। यही है, जब उसने नोड्स के बीच रिकॉर्ड का पीछा करना शुरू किया, तो जान लें कि मंडली आपको देख रही है और शायद उसे मंजूर नहीं है।

हालाँकि, पहले तरीकों की तुलना में, जीवन में सुधार हुआ है - जब एक शार्क को जोड़ना / हटाना, हम पहले से ही सभी रिकॉर्ड नहीं देख रहे हैं, लेकिन केवल एक हिस्सा है, और केवल एक हिस्सा शिफ्ट करते हैं।

ध्यान दें, सवाल यह है कि क्या इसमें और सुधार किया जा सकता है? और लोडिंग शार्ड्स की एकरूपता में भी सुधार करें? वे कहते हैं कि यह संभव है!

अधिक मज़ा #4। मिलन स्थल / एचआरडब्ल्यू

अगला सरल विचार (सामग्री शैक्षिक है, इसलिए कुछ भी जटिल नहीं है): shard_id = arg max hash(object_id, shard_id)।

मुझे नहीं पता कि इसे रेंडीज़वस हैशिंग क्यों कहा जाता है, लेकिन मुझे पता है कि इसे हाईएस्ट रैंडम वेट क्यों कहा जाता है। इसे इस तरह कल्पना करना बहुत आसान है:

उदाहरण के लिए, हमारे पास 16 शार्क हैं। प्रत्येक वस्तु (स्ट्रिंग) के लिए जिसे कहीं रखने की आवश्यकता है, हम शार्क संख्या से वस्तु के आधार पर 16 हैश की गणना करते हैं। जिसके पास उच्चतम हैश मान है वह जीतता है।

यह तथाकथित एचआरडब्ल्यू-हैशिंग उर्फ ​​रेंडेवस हैशिंग है। एक छड़ी के रूप में गूंगा, एक शार्क की संख्या की गणना करने की योजना, सबसे पहले, हलकों की तुलना में आंख पर आसान होती है और दूसरी ओर एक समान भार देती है।

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

एक और समस्या यह है कि यह बड़ी संख्या में शार्क के साथ कम्प्यूटेशनल रूप से भारी है।

अधिक मज़ा # 5। अधिक तकनीकें

दिलचस्प बात यह है कि अनुसंधान स्थिर नहीं रहता है और Google हर साल कुछ नई अंतरिक्ष प्रौद्योगिकी प्रकाशित करता है:

  • जंप हैश - Google '2014।
  • मल्टी प्रोब—गूगल '2015।
  • मैग्लेव-गूगल '2016।

यदि आप इस विषय में रुचि रखते हैं, तो आप कई शोध प्रबंध पढ़ सकते हैं। मैं इस डेटा को यह स्पष्ट करने के लिए प्रस्तुत करता हूं कि समस्या हल नहीं हुई है, ऐसा कोई सुपर-सॉल्यूशन नहीं है जिसे सभी डेटाबेस में लागू किया जा सके। अब तक, लोग शोध प्रबंधों का बचाव करते हैं।

निष्कर्ष

गैलियस जूलियस सीज़र के नाम पर शार्पिंग नामक एक महत्वपूर्ण बुनियादी तकनीक है: "फूट डालो और राज करो, शासन करो और बांटो!"। यदि डेटा एक सर्वर में फिट नहीं होता है, तो इसे 20 सर्वरों में विभाजित करना आवश्यक है।

यह सब जानने के बाद, किसी को यह आभास हो जाना चाहिए कि बेहतर होगा कि शार्क न करें। यदि आप तय करते हैं कि शार्क न करना बेहतर होगा, तो यह सही भावना है। यदि आप $100 के लिए सर्वर में मेमोरी जोड़ सकते हैं और कुछ भी शार्प नहीं कर सकते हैं, तो आपको यह करना चाहिए। शार्डिंग करते समय, एक जटिल वितरित प्रणाली डेटा को आगे और पीछे स्थानांतरित करने के साथ दिखाई देगी, जहां कोई नहीं जानता कि डेटा को ढेर कर रहा है। अगर इससे बचा जा सकता है, तो इससे बचना चाहिए।

इसे हाथ से न करना बेहतर है, यह बेहतर है कि "आधार" (खोज, डीएफएस, ...) खुद को तेज कर सके। किसी भी मामले में, जल्दी या बाद में, उच्च भार आएगा और किसी तरह डेटा को विभाजित करना होगा। यह एक तथ्य नहीं है कि भले ही आधार इसे स्वयं कर सकता है, आपको कोई समस्या नहीं होगी। एल्गोरिथम कट्टरवाद के बारे में याद रखें - आपको यह समझने की आवश्यकता है कि अंदर सब कुछ कैसे काम करता है।

पहली बार शार्डिंग सेट करते समय, F() सावधानी से चुनें, अनुरोधों, नेटवर्क आदि के बारे में सोचें। लेकिन तैयार हो जाइए, आपको शायद 2 बार चुनना होगा और कम से कम एक बार आपको सब कुछ फिर से करना होगा।