MySQL का उपयोग नियमित रूप से 100+ जीबी टेबल पर मल्टी-वे जॉइन करने के लिए करें?


11

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

मैं खुद को एक सॉफ्टवेयर डेवलपर मानता हूं, डेटाबेस विशेषज्ञ नहीं। इसलिए मैं यहां पोस्ट कर रहा हूं। उम्मीद है कि बहुत अधिक डेटाबेस विशेषज्ञता वाला कोई व्यक्ति मुझे सलाह दे सकता है।

उपयोगकर्ताओं की अपेक्षाकृत बड़ी संख्या के साथ, लेकिन फेसबुक नंबरों की तरह कुछ भी नहीं, मुझे उम्मीद है कि एक डीबी है जो इस तरह दिखता है:

एक "बड़ी तालिका":

  • 250 मिलियन रिकॉर्ड
  • 20 कॉलम
  • लगभग 100 जीबी डेटा
  • अनुक्रमित बिगिन (20) विदेशी कुंजी है
  • एक अनुक्रमित varchar (500) string_id कॉलम है
  • एक इंट (11) "मान" कॉलम है

4 अन्य टेबल:

  • 10 मिलियन रिकॉर्ड प्रत्येक
  • लगभग 2 - 4 जीबी डेटा प्रत्येक
  • इनमें से प्रत्येक टेबल में 4 - 8 कॉलम हैं
  • एक कॉलम डेटटाइम है
  • एक स्तंभ varchar (500) string_id कॉलम है
  • इन तालिकाओं में से प्रत्येक में से एक या दो स्तंभ एक चयन में चुने जाएंगे

इन तालिकाओं में से एक का उपयोग औसत भंडारण के लिए किया जाता है - इसका स्कीमा bigint (20) id, varchar (20) string_id, datetime date_created, float average_value है

मैं क्या करना चाहता हूँ - दो अपेक्षाकृत महंगे प्रश्न:

  1. नए औसत मूल्यों की गणना करें:

    • एक विदेशी कुंजी का उपयोग करके, बड़ी तालिका से कई मिलियन अलग-अलग रिकॉर्ड का चयन करें।
    • एक नए औसत की गणना करें, string_id द्वारा समूहीकरण।
    • औसत तालिका में परिणाम डालें।
    • जैसा कि वर्तमान में निर्मित है, यह क्वेरी दो जोड़ का उपयोग करती है।
  2. सेवारत उपयोगकर्ताओं के लिए डी-सामान्यीकृत, केवल-पढ़ने के लिए रिकॉर्ड बनाएं:

    • बड़ी तालिका से 1,000-40,000 रिकॉर्ड से कहीं भी चयन करने के लिए एक विदेशी कुंजी का उपयोग करें।
    • स्ट्रिंग आईडी कॉलम के साथ नवीनतम रिकॉर्ड पर अन्य चार तालिकाओं में से प्रत्येक के साथ जुड़ें।
    • परिणामों को डी-सामान्यीकृत तालिका में डालें।
    • ये रिकॉर्ड उपयोगकर्ताओं को जानकारी प्रदर्शित करने के लिए फ्रंट-एंड द्वारा उपयोग के लिए हैं।
    • जैसा कि वर्तमान में निर्मित है, यह क्वेरी चार जोड़ का उपयोग करती है।

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

इन प्रश्नों में से प्रत्येक वर्तमान में MySQL में कुछ सेकंड्स में "डेटा टेबल" में 100K रिकॉर्ड के साथ एक बहुत कम अंत मशीन पर चलता है। मैं स्केल करने की मेरी क्षमता और स्केलिंग की लागत दोनों के बारे में चिंतित हूं।

प्रश्न :

  1. क्या यह दृष्टिकोण ध्वनि लगता है? क्या बड़ी तस्वीर के नजरिए से इसमें कुछ गलत है?
  2. क्या RDBMS सही उपकरण है, या क्या मुझे Hadoop परिवार में किसी चीज़ की तरह अन्य "बड़े डेटा" समाधानों को देखना चाहिए? मेरा झुकाव RDBMS का उपयोग करना है क्योंकि डेटा संरचित है और संबंधपरक मॉडल में अच्छी तरह से फिट बैठता है। हालांकि एक निश्चित बिंदु पर, यह मेरी समझ है कि मैं अब RDBMS का उपयोग करने में सक्षम नहीं हो सकता। क्या यह सच है? इस स्विच की आवश्यकता कब होगी?
  3. क्या ये काम करेगा? क्या उचित समय में इन प्रश्नों को चलाया जा सकता है? मैं क्वेरी # 1 के लिए शायद घंटों इंतजार कर सकता हूं, लेकिन क्वेरी # 2 मिनटों में समाप्त हो जानी चाहिए।
  4. हार्डवेयर परिप्रेक्ष्य से मुझे क्या विचार करना चाहिए? मेरी रैम और सीपीयू अड़चनें क्या हैं? मुझे लगता है कि RAM में अनुक्रमित रखना महत्वपूर्ण है। क्या कुछ और है जिस पर मुझे विचार करना चाहिए?
  5. कुछ बिंदु पर मुझे संभवतः अपने डेटा का विभाजन करना होगा और कई सर्वरों का उपयोग करना होगा। क्या मेरा उपयोग मामला ऐसा लगता है कि यह पहले से ही उस श्रेणी में है, या मैं थोड़ी देर के लिए एक भी मशीन को लंबवत रूप से स्केल कर पाऊंगा? क्या यह 10x डेटा के साथ काम करेगा? 100x?

यह पूरी तरह से जवाब देने के लिए कठिन है। हो सकता है कि आप MySQL क्वेरी प्रदर्शन विशेषताओं के बारे में सामान्य रूप से शोध करना बेहतर समझते हों, ताकि आप जान सकें कि आप क्या उम्मीद कर सकते हैं ।; एक चीज जो आप हमेशा कर सकते हैं वह है सर्वर में 20 डिस्क्स। इसलिए आप 3GB / s पर पढ़ सकते हैं। लेकिन मुझे लगता है कि आप पूरी तरह से केवल सॉफ्टवेयर के जवाब के बाद हैं।
usr

जवाबों:


4

क्या आपने अधिक डेटा जमा करने और इसे बेंचमार्क करने की कोशिश की है? 100K पंक्तियाँ असंगत हैं। 250M या 500M आज़माएं जैसे आप उम्मीद कर रहे हैं कि आपको संभालना होगा और देखना होगा कि अड़चनें कहाँ हैं।

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

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

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

एक हार्डवेयर परिप्रेक्ष्य से, आपको यह देखने के लिए परीक्षण करना होगा कि आपका प्लेटफ़ॉर्म कैसा है। कभी-कभी याददाश्त जरूरी है। अन्य बार यह डिस्क I / O है। यह वास्तव में इस बात पर निर्भर करता है कि आप डेटा के साथ क्या कर रहे हैं। आपको अपने CPU उपयोग पर पूरा ध्यान देने की आवश्यकता है और IO के उच्च स्तर की तलाश करें ताकि पता चल सके कि समस्या कहाँ है।

जब भी संभव हो, अपने डेटा को कई प्रणालियों में विभाजित करें। यदि आप बहादुर महसूस कर रहे हैं, तो आप MySQL क्लस्टर का उपयोग कर सकते हैं, या बस MySQL के कई स्वतंत्र उदाहरणों को स्पिन कर सकते हैं, जहां प्रत्येक कुछ विभाजन योजना का उपयोग करते हुए पूर्ण डेटा सेट का एक मनमाना हिस्सा स्टोर करता है जो समझ में आता है।


@tadman आपकी सलाह के लिए धन्यवाद। मुझे लगता है कि वास्तव में इसे आज़माने के लिए कोई विकल्प नहीं है। मैंने इसे 250M पंक्तियों के साथ बेंचमार्क नहीं किया है क्योंकि मैं पहली बार यह सुनिश्चित करना चाहता था कि मेरे दृष्टिकोण के बारे में स्पष्ट रूप से कुछ भी गलत नहीं था। ऐसा लगता है जैसे वहाँ नहीं है। इसके अलावा, इतना डेटा प्राप्त करना, और इसे इस तरह से करना कि कुछ हद तक यथार्थवादी है एक चुनौती है जिसे मैंने अभी तक नहीं सुलझाया है। मेरे पास डेटा को विभाजित करने के कुछ संभावित तरीके हैं। मुझे लगता है कि मैं अगले बस अपने डेटा को
रैंप

1

सारांश सारणी।

हर दिन, दिन के डेटा के लिए कुल जानकारी की गणना करें। इसे "सारांश" तालिका में रखें। उनके खिलाफ अपनी पूछताछ करें। आसानी से उपवास के 10 गुना।

आगे की चर्चा के लिए, कृपया प्रदान करें

  • शो टेबल (जैसा कि यह अब खड़ा है)
  • तालिका आकार (जिसका आपने उल्लेख किया है)
  • प्रस्तावित चयन

कुछ स्पष्ट बातें ...

  • BIGINT को शायद ही कभी वारंट किया गया हो। इसमें 8 बाइट्स लगते हैं। INT UNSIGNED 4 लेता है और मानों को 0..4 बिलियन की अनुमति देता है। और मेडमिंट इत्यादि है।
  • 'तथ्य' तालिका पर कई सूचकांक आमतौर पर एक गंभीर प्रदर्शन समस्या है, विशेष रूप से INSERT के लिए। क्या आप वहाँ एक मुद्दा है?
  • DATETIME 8 बाइट्स है; TIMESTAMP 4 है
  • स्पष्ट रूप से प्रमुख कुंजी अनुरूप अच्छे हैं, लेकिन महंगा है
  • जॉइन एक प्रदर्शन समस्या हो सकती है या नहीं; चयन और सृजन देखने की जरूरत है।
  • 'बड़े' MySQL डेटाबेस के लिए 100GB एक अच्छा आकार है; मुझे संदेह है कि यह हडूप के बिना काम करने के लिए बनाया जा सकता है, आदि। मैं अब ऐसे एक डीबी से निपटता हूं - अधिकांश यूआई पृष्ठ एक सेकंड के तहत जवाब देते हैं, भले ही डेटा काफी शामिल हो।
  • क्या आप किसी बिंदु पर 'शुद्धिकरण' डेटा होंगे? (इससे पार्टिशनिंग के लिए मुख्य उपयोग का मामला बनता है।)

"छोटा -> अधिक कैचीबल -> तेज


0

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

मैं तदमन से सहमत हूं। सबसे अच्छा यह है कि आप जिस तरह के सिस्टम की उम्मीद कर रहे हैं, उस तरह के डेटा के साथ इसे प्रोफाइल करें।


जैसा कि मैंने अपनी पोस्ट में उल्लेख किया है, विचार एक ऐसी क्वेरी पर निर्भर करते हैं जो दसियों लाख रिकॉर्ड के साथ तालिकाओं में चार जोड़ का उपयोग करती है, इसलिए मैं वास्तव में नहीं देखता कि भौतिक दृष्टिकोण कैसे मदद करने वाला है।
xnickmx

ट्रिगर इस आकार के डेटाबेस के लिए पर्याप्त तेज़ नहीं हो सकते हैं। प्रति सेकंड कितने INSERT हो रहे हैं?
रिक जेम्स

1
@xnickmx यदि बहुत सारे इन्सर्ट / अपडेट नहीं हैं, तो ट्रिगर डेटा को सिंक में रखना आसान / आसान बनाता है। अगर इसे आवेषण / अपडेट के लिए तेज़ी से जाने की आवश्यकता है, तो उन्हें कुछ इस तरह से कतारबद्ध करें: blog.shlomoid.com/2008/04/… या अपना खुद का बेक करें। इस तरह से आपको नया डेटा प्राप्त करने के लिए मौजूदा 100 मिलियन पंक्ति तालिकाओं के खिलाफ शामिल होने की आवश्यकता नहीं है जब से ट्रिगर की आग लग जाती है, तो आप इस तथ्य का लाभ उठाते हैं कि आप नए डेटा को ठीक से जानते हैं और इसे tx के भाग के रूप में स्पष्ट कर सकते हैं। या इसे बाद में अपभ्रंश के लिए कतारबद्ध करें।
wes.stueve 16

@ रिकजम्स सहमत। आपको इस तरह की रणनीति के लिए आवेषण की मात्रा को ध्यान में रखना चाहिए और उन्हें कितनी तेजी से प्रक्रिया करना होगा।
wes.stueve
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.