1.1 शार्डिंग म्हणजे काय?

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

मला एकही टर्मिनोलॉजिकल मानक आढळले नाही जे संस्थापक वडिलांनी मंजूर केले असेल आणि ISO द्वारे प्रमाणित केले जाईल. वैयक्तिक आंतरिक खात्री ही अशी आहे: सरासरी विभाजन करणे म्हणजे स्वैरपणे घेतलेल्या मार्गाने “पायाचे तुकडे करणे” होय.

  • अनुलंब विभाजन - स्तंभानुसार. उदाहरणार्थ, 60 स्तंभांमध्ये दोन अब्ज रेकॉर्ड असलेली एक विशाल टेबल आहे. असे एक महाकाय टेबल ठेवण्याऐवजी, आम्ही प्रत्येकी 2 अब्ज रेकॉर्डच्या किमान 60 महाकाय टेबल्स ठेवतो - आणि हे स्तंभ आधार नसून उभ्या विभाजन (परिभाषेचे उदाहरण म्हणून) आहे.
  • क्षैतिज विभाजन - आम्ही कदाचित सर्व्हरच्या आत ओळीने ओळ कापतो.

येथे विचित्र क्षण म्हणजे क्षैतिज विभाजन आणि शार्डिंगमधील सूक्ष्म फरक. माझे तुकडे केले जाऊ शकतात, परंतु ते काय आहे हे मी निश्चितपणे सांगू शकत नाही. अशी भावना आहे की शार्डिंग आणि क्षैतिज विभाजन एकाच गोष्टीबद्दल आहे.

सर्वसाधारणपणे, जेव्हा तुमच्याकडे डेटाबेस नसेल, परंतु दस्तऐवज स्टोअर नसेल तर डेटाबेस किंवा दस्तऐवज, ऑब्जेक्ट्सचे प्रो-कलेक्शन, जेव्हा एक मोठे टेबल ऑब्जेक्ट्सद्वारे काटलेले असते तेव्हा शार्डिंग असते . म्हणजेच, 2 अब्ज वस्तूंमधून, तुकडे निवडले जातात मग ते कितीही आकाराचे असले तरीही. प्रत्येक वस्तूच्या आत असलेल्या वस्तूंचे स्वतः तुकडे केले जात नाहीत, आम्ही त्यांना वेगळ्या स्तंभांमध्ये ठेवत नाही, म्हणजे, आम्ही त्यांना वेगवेगळ्या ठिकाणी बॅचमध्ये ठेवतो.

सूक्ष्म शब्दशास्त्रीय फरक आहेत. उदाहरणार्थ, तुलनेने बोलायचे झाल्यास, पोस्टग्रेस डेव्हलपर असे म्हणू शकतात की क्षैतिज विभाजन म्हणजे जेव्हा सर्व टेबल्स ज्यामध्ये मुख्य टेबलचे विभाजन केले जाते त्याच स्कीमामध्ये असते आणि जेव्हा वेगवेगळ्या मशीनवर, हे आधीच शार्डिंग असते.

सामान्य अर्थाने, विशिष्ट डेटाबेस आणि विशिष्ट डेटा मॅनेजमेंट सिस्टमच्या शब्दावलीशी जोडल्याशिवाय, अशी भावना आहे की शार्डिंग म्हणजे फक्त ओळीने / दस्तऐवजानुसार दस्तऐवजाचे तुकडे करणे, आणि इतकेच - इतकेच.

मी टिपिकलवर जोर देतो. या अर्थाने की आम्ही हे सर्व 2 अब्ज दस्तऐवजांना 20 तक्त्यांमध्ये कापण्यासाठी करत नाही, ज्यापैकी प्रत्येक अधिक आटोपशीर असेल, परंतु ते अनेक कोर, अनेक डिस्क किंवा अनेक भिन्न भौतिक किंवा आभासी सर्व्हरवर वितरित करण्यासाठी.

1.2 अविभाज्य विभाजित करा

असे समजले जाते की आम्ही असे करतो जेणेकरून प्रत्येक शार्ड - डेटाचा प्रत्येक तुकडा - अनेक वेळा प्रतिकृती बनविला जातो. पण खरोखर, नाही.

INSERT INTO docs00 
SELECT * FROM documents WHERE (id%16)=0 
... 
 
INSERT INTO docs15 
SELECT * FROM documents WHERE (id%16)=15 

खरं तर, जर तुम्ही डेटाचे असे स्लाइसिंग केले, आणि तुमच्या शूर लॅपटॉपवर MySQL वरील एका विशाल SQL टेबलवरून, तुम्ही एका लॅपटॉपच्या पलीकडे न जाता, एकच स्कीमा, एकच डेटाबेस नाही, इत्यादी 16 लहान टेबल्स तयार कराल. . आणि असेच. - तेच आहे, तुमच्याकडे आधीच शार्डिंग आहे.

याचा परिणाम पुढीलप्रमाणे होतो:

  • बँडविड्थ वाढते.
  • लेटन्सी बदलत नाही, म्हणजे, प्रत्येकाला, म्हणून बोलायचे तर, या प्रकरणात कामगार किंवा ग्राहक, स्वतःचे मिळवतात. वेगवेगळ्या विनंत्या एकाच वेळी पूर्ण केल्या जातात.
  • किंवा दोन्ही, आणि दुसरे, आणि उच्च उपलब्धता (प्रतिकृती).

बँडविड्थ का? आमच्याकडे कधीकधी डेटाचे असे खंड असू शकतात जे फिट होत नाहीत - हे कुठे स्पष्ट नाही, परंतु ते बसत नाहीत - 1 {kernel | डिस्क | सर्व्हर | ...}. पुरेशी संसाधने नाहीत, एवढेच. या मोठ्या डेटासेटसह कार्य करण्यासाठी, तुम्हाला तो कट करणे आवश्यक आहे.

विलंब का? एका कोअरवर, 2 बिलियन पंक्तींचे टेबल स्कॅन करणे हे 20 कोअरवर 20 टेबल स्कॅन करण्यापेक्षा 20 पटीने कमी आहे, ते समांतरपणे करत आहे. एकाच संसाधनावर डेटावर खूप हळू प्रक्रिया केली जाते.

उच्च उपलब्धता का? किंवा आम्ही दोन्ही एकाच वेळी करण्यासाठी डेटा कापतो आणि त्याच वेळी प्रत्येक शार्डच्या अनेक प्रती - प्रतिकृती उच्च उपलब्धता सुनिश्चित करते.

1.3 एक साधे उदाहरण "हे हाताने कसे करावे"

32 दस्तऐवजांसाठी चाचणी सारणी test.documents वापरून सशर्त शार्डिंग कापले जाऊ शकते आणि या सारणीतून 16 चाचणी सारण्या तयार करणे, प्रत्येक test.docs00, 01, 02, ..., 15 असे अंदाजे 2 दस्तऐवज.

INSERT INTO docs00 
SELECT * FROM documents WHERE (id%16)=0 
... 
 
INSERT INTO docs15 
SELECT * FROM documents WHERE (id%16)=15 

कशासाठी? कारण 1 ते 32 पर्यंत id कसे वितरीत केले जाते हे आम्हाला माहित नाही, तर प्रत्येकी 2 कागदपत्रे असतील, अन्यथा नाही.

आम्ही ते का येथे करतो. आम्ही 16 टेबल बनवल्यानंतर, आम्हाला आवश्यक असलेल्या 16 आम्ही "हप्त" करू शकतो. आम्ही काय मारतो याची पर्वा न करता, आम्ही या संसाधनांना समांतर करू शकतो. उदाहरणार्थ, डिस्कमध्ये पुरेशी जागा नसल्यास, वेगळ्या डिस्कवर या टेबल्सचे विघटन करणे अर्थपूर्ण आहे.

हे सर्व, दुर्दैवाने, विनामूल्य नाही. मला शंका आहे की कॅनॉनिकल SQL मानकाच्या बाबतीत (मी बर्याच काळापासून SQL मानक पुन्हा वाचले नाही, कदाचित ते बर्याच काळापासून अद्यतनित केले गेले नाही), कोणत्याही SQL सर्व्हरला सांगण्यासाठी कोणतेही अधिकृत प्रमाणित वाक्यरचना नाही. : "प्रिय SQL सर्व्हर, मला 32 शार्ड बनवा आणि त्यांना 4 डिस्कमध्ये विभाजित करा. परंतु वैयक्तिक अंमलबजावणीमध्ये, मूलभूतपणे समान गोष्ट करण्यासाठी एक विशिष्ट वाक्यरचना असते. PostgreSQL मध्ये विभाजनाची यंत्रणा आहे, MySQL मध्ये MariaDB आहे, ओरॅकलने हे सर्व खूप पूर्वी केले असावे.

तरीसुद्धा, जर आम्ही ते हाताने, डेटाबेस समर्थनाशिवाय आणि मानकांच्या चौकटीत केले तर आम्ही डेटा प्रवेशाच्या जटिलतेसह सशर्त पैसे देतो . जिथे एक साधा SELECT * FROM दस्तऐवज WHERE id=123 होता, आता 16 x SELECT * FROM docsXX. आणि आम्ही की द्वारे रेकॉर्ड मिळविण्याचा प्रयत्न केला तर ते चांगले आहे. जर आम्ही रेकॉर्डची लवकर श्रेणी मिळवण्याचा प्रयत्न करत असू तर अधिक मनोरंजक. आता (आम्ही, मी जोर देत असलो तर, मूर्ख आहोत आणि मानकांच्या चौकटीत राहिलो तर) या 16 SELECT * FROM चे परिणाम ऍप्लिकेशनमध्ये एकत्र करावे लागतील.

तुम्ही कोणत्या कामगिरीतील बदलाची अपेक्षा करू शकता?

  • अंतर्ज्ञानाने - रेखीय.
  • सैद्धांतिकदृष्ट्या - sublinear, कारण Amdahl कायदा.
  • व्यावहारिकदृष्ट्या, कदाचित जवळजवळ रेखीय, कदाचित नाही.

खरं तर, योग्य उत्तर अज्ञात आहे. शार्डिंग तंत्राच्या चपखल वापराने, तुम्ही तुमच्या ऍप्लिकेशनच्या कार्यक्षमतेत लक्षणीय सुपर-लिनियर डिग्रेडेशन साध्य करू शकता आणि डीबीए देखील रेड-हॉट पोकरसह धावून येईल.

हे कसे साध्य करता येईल ते पाहूया. हे स्पष्ट आहे की फक्त PostgreSQL shards=16 वर सेटिंग सेट करणे, आणि नंतर ते स्वतःच बंद होते, हे मनोरंजक नाही. आपण शार्डिंगपासून 32 पटीने 16 पटीने मंद होत असल्याची खात्री कशी करता येईल याचा विचार करूया - हे कसे करू नये या दृष्टिकोनातून हे मनोरंजक आहे.

वेग वाढवण्याचे किंवा कमी करण्याचे आमचे प्रयत्न नेहमीच क्लासिक्समध्ये जातील - चांगला जुना अमदाहल कायदा, जो म्हणतो की कोणत्याही विनंतीचे कोणतेही परिपूर्ण समांतर नाही, नेहमीच काही सुसंगत भाग असतो.

1.4 अमदहल कायदा

नेहमी एक क्रमिक भाग असतो.

क्वेरी अंमलबजावणीचा नेहमीच एक भाग असतो जो समांतर असतो आणि नेहमी समांतर नसलेला भाग असतो. जरी तुम्हाला अगदी समांतर क्वेरी वाटत असली तरीही, प्रत्येक शार्डमधून मिळालेल्या पंक्तींमधून तुम्ही क्लायंटला पाठवणार असलेल्या निकाल पंक्तीचा संग्रह नेहमीच असतो आणि तो नेहमी क्रमवार असतो.

नेहमी काही सुसंगत भाग असतो. हे लहान असू शकते, सामान्य पार्श्वभूमीच्या विरूद्ध पूर्णपणे अदृश्य असू शकते, ते अवाढव्य असू शकते आणि त्यानुसार, समांतरीकरणावर जोरदार प्रभाव पाडतो, परंतु ते नेहमीच अस्तित्वात असते.

याव्यतिरिक्त, त्याचा प्रभाव बदलत आहे आणि लक्षणीय वाढू शकतो, उदाहरणार्थ, जर आपण आमची सारणी कापली तर - चला स्टेक्स वाढवू - 64 रेकॉर्डवरून 4 रेकॉर्डच्या 16 टेबलमध्ये, हा भाग बदलेल. अर्थात, एवढ्या प्रचंड प्रमाणात डेटा पाहता, आम्ही मोबाईल फोन आणि 2 MHz 86 प्रोसेसरवर काम करत आहोत आणि आमच्याकडे एकाच वेळी उघड्या ठेवता येतील अशा पुरेशा फाइल्स नाहीत. वरवर पाहता, अशा इनपुटसह, आम्ही एका वेळी एक फाइल उघडतो.

  • ते एकूण = सिरीयल + समांतर होते . जेथे, उदाहरणार्थ, समांतर DB मधील सर्व काम आहे आणि सीरियल क्लायंटला निकाल पाठवत आहे.
  • Total2 = सिरीयल + समांतर/N + Xserial झाले . उदाहरणार्थ, जेव्हा एकूण क्रमाने, Xserial>0.

या साध्या उदाहरणाने, मी काही Xserial दिसते हे दाखवण्याचा प्रयत्न करत आहे. नेहमी एक क्रमिक भाग असतो या वस्तुस्थितीव्यतिरिक्त आणि आम्ही डेटासह समांतरपणे कार्य करण्याचा प्रयत्न करत आहोत या वस्तुस्थितीव्यतिरिक्त, हा डेटा स्लाइसिंग प्रदान करण्यासाठी एक अतिरिक्त भाग आहे. साधारणपणे सांगायचे तर, आम्हाला याची आवश्यकता असू शकते:

  • डेटाबेसच्या अंतर्गत शब्दकोशामध्ये या 16 टेबल्स शोधा;
  • फायली उघडा;
  • मेमरी वाटप करा;
  • स्मृती रद्द करा;
  • विलीन परिणाम;
  • कोर दरम्यान समक्रमित करा.

काही आउट-ऑफ-सिंक प्रभाव अजूनही दिसतात. ते क्षुल्लक असू शकतात आणि एकूण वेळेपैकी एक अब्जावा भाग व्यापू शकतात, परंतु ते नेहमी शून्य नसतात आणि नेहमीच असतात. त्यांच्या मदतीने, आम्ही शार्डिंगनंतर नाटकीयपणे कामगिरी गमावू शकतो.

हे Amdahl च्या कायद्याबद्दल एक प्रमाणित चित्र आहे. येथे महत्त्वाची गोष्ट अशी आहे की रेषा, ज्या आदर्शपणे सरळ असाव्यात आणि रेखीय वाढल्या पाहिजेत, त्या एसीम्प्टोटमध्ये धावतात. परंतु इंटरनेटवरील आलेख वाचनीय नसल्यामुळे, मी माझ्या मते, संख्यांसह अधिक व्हिज्युअल तक्ते बनवल्या आहेत.

समजा आमच्याकडे विनंती प्रक्रियेचा काही क्रमिक भाग आहे जो फक्त 5% घेतो: अनुक्रमांक = 0.05 = 1 / 20 .

अंतर्ज्ञानाने, असे दिसते की विनंती प्रक्रियेचा फक्त 1/20 भाग घेणार्‍या अनुक्रमिक भागासह, जर आम्ही 20 कोरसाठी विनंती प्रक्रियेला समांतर केले, तर ते सुमारे 20 होईल, सर्वात वाईट परिस्थितीत 18 पट वेगवान होईल.

खरं तर, गणित ही एक हृदयहीन गोष्ट आहे :

भिंत = 0.05 + 0.95/num_cores, स्पीडअप = 1 / (0.05 + 0.95/num_cores)

असे दिसून आले की जर आपण काळजीपूर्वक गणना केली तर, 5% च्या अनुक्रमित भागासह, वेग 10 पट (10.3) असेल, जो सैद्धांतिक आदर्शाच्या तुलनेत 51% आहे.

8 कोर = ५.९ = 74%
10 कोर = ६.९ = ६९%
20 कोर = 10.3 = ५१%
40 कोर = १३.६ = 34%
128 कोर = १७.४ = 14%

20 कोर (20 डिस्क्स, जर तुम्हाला आवडत असतील तर) ज्या कामावर काम करायचे त्या कामासाठी वापरल्यानंतर, आम्हाला सैद्धांतिकदृष्ट्या 20 पेक्षा जास्त वेळा प्रवेग देखील मिळणार नाही, परंतु व्यवहारात - खूपच कमी. शिवाय, समांतरांच्या संख्येत वाढ झाल्यामुळे, अकार्यक्षमता मोठ्या प्रमाणात वाढते.

जेव्हा फक्त 1% अनुक्रमित कार्य शिल्लक राहते आणि 99% समांतर केले जाते, तेव्हा स्पीडअप मूल्ये काही प्रमाणात सुधारतात:

8 कोर = 7.5 = 93%
16 कोर = १३.९ = ८७%
32 कोर = २४.४ = 76%
64 कोर = 39.3 = ६१%

परिपूर्ण थर्मोन्यूक्लियर क्वेरीसाठी, जी नैसर्गिकरित्या पूर्ण होण्यासाठी तास लागतात आणि तयारीचे काम आणि निकालाच्या असेंब्लीला फारच कमी वेळ लागतो (क्रमांक = 0.001), आम्ही आधीच चांगली कार्यक्षमता पाहू:

8 कोर = 7.94 = 99%
16 कोर = १५.७६ = 99%
32 कोर = 31.04 = 97%
64 कोर = 60.20 = 94%

कृपया लक्षात ठेवा की आम्ही कधीही 100% पाहणार नाही . विशेषतः चांगल्या प्रकरणांमध्ये, आपण पाहू शकता, उदाहरणार्थ, 99.999%, परंतु अगदी 100% नाही.