प्रतिनिधि इंटरव्यू विषय

डेटा इंजीनियरिंग इंटरव्यू: DAG-आधारित क्वेरी व्यूज़ के लिए एक कैश डिज़ाइन करें

डेटाकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक एनालिटिक्स प्लेटफ़ॉर्म में 500 मटेरियलाइज़्ड क्वेरी व्यूज़ हैं जो 20 की गहराई तक निर्भरता DAGs बनाते हैं। पाँच मिनट के फ्रेशनेस लक्ष्य, आंशिक विफलताओं, बैकफ़िल्स और हॉट व्यूज़ के साथ 10,000 क्वेरी प्रति सेकंड के लिए एक कैश और रिफ्रेश सिस्टम डिज़ाइन करें।

प्रश्न और दायरा

प्रत्येक व्यू सोर्स टेबल या अन्य व्यूज़ पर एक क्वेरी है। एक सोर्स बदलाव वंशजों (descendants) को अमान्य (invalidate) कर देता है, लेकिन प्रत्येक वंशज की तुरंत पुनर्गणना करना बहुत महंगा है। सिस्टम को एक वर्जन्ड परिणाम देना चाहिए, फ्रेशनेस को प्रदर्शित करना चाहिए, और पैरेंट व्यूज़ की असंगत पीढ़ियों (incompatible generations) को कभी संयोजित नहीं करना चाहिए। मान लें कि रिफ्रेश का कार्य एसिंक्रोनस हो सकता है और रिकवरी के लिए एक पूर्ण पुनर्निर्माण (full rebuild) उपलब्ध रहता है।

इंटरव्यूअर क्या जांच रहा है

  • निर्भरता किनारों (dependency edges), वर्जन्स, अमान्यता (invalidation), और टोपोलॉजिकल रिफ्रेश क्रम का मॉडलिंग करना।
  • बदलाव की मात्रा और क्वेरी के स्वरूप से वृद्धिशील (incremental) बनाम पूर्ण पुनर्गणना का चयन करना।
  • बासी (stale) परिणामों, आंशिक विफलताओं, बैकफ़िल्स, हॉट कीज़ और कैश निष्कासन (cache eviction) को संभालना।
  • वंशावली (lineage), मैनिफ़ेस्ट, चेकसम और रीप्ले करने योग्य इवेंट्स के साथ शुद्धता को प्रमाणित करना।

स्पष्टीकरण के लिए पूछे जाने वाले सवाल

पूछें कि क्या प्रत्येक क्वेरी का एक फ्रेशनेस SLO है, क्या जॉइन्स को वृद्धिशील रूप से बनाए रखा जा सकता है, अपडेट और डिलीट कैसे आते हैं, और क्या पाठक (readers) किसी त्रुटि के बजाय बासी उत्तर पसंद करते हैं। यदि किसी व्यू में गैर-इनवर्टीबल समुच्चय (non-invertible aggregates) शामिल हैं, तो बदली हुई पंक्ति के लिए व्यापक पुनर्गणना की आवश्यकता हो सकती है; यदि कोई व्यू केवल जोड़ने योग्य (append-only) है, तो डेल्टा रिफ्रेश सस्ता पड़ता है।

30-सेकंड का उत्तर

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

चरण-दर-चरण गहन विश्लेषण

1. DAG और पीढ़ियों का प्रतिनिधित्व करें

प्रत्येक व्यू को एक स्थिर ID, क्वेरी परिभाषा, पैरेंट IDs और पीढ़ी दें। एक रिफ्रेश योजना एक लक्षित सोर्स वॉटरमार्क ले जाती है और रिकॉर्ड करती है कि उसने किस पैरेंट पीढ़ी का उपभोग किया है। यदि रिफ्रेश के मध्य में पैरेंट बदल गया है तो प्रकाशन को अस्वीकार करें; परिणामों को चुपचाप मिलाने के बजाय एक नए वॉटरमार्क से पुनः प्रयास करें।

2. डेल्टा या पूर्ण रिफ्रेश चुनें

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

3. अमान्यता को शेड्यूल करें और हॉट व्यूज़ को नियंत्रित करें

कई सोर्स इवेंट्स को एक लक्षित वॉटरमार्क में संयोजित करें, फिर प्रभावित नोड्स को प्रति पीढ़ी एक बार प्रोसेस करें। क्वेरी की मांग और फ्रेशनेस ऋण द्वारा व्यूज़ को प्राथमिकता दें, लेकिन एक हॉट अपस्ट्रीम को कंप्यूट समाप्त करने से रोकने के लिए प्रति सोर्स समवर्ती कार्य (concurrent work) को सीमित करें। व्यू पैरामीटर्स और पीढ़ी द्वारा लोकप्रिय परिणामों को कैश करें; प्रत्येक की को व्यक्तिगत रूप से हटाने के बजाय पीढ़ी द्वारा अमान्य करें।

4. पुनर्प्राप्ति, बैकफ़िल, और शुद्धता सिद्ध करें

अमान्यता इवेंट्स और रिफ्रेश मैनिफ़ेस्ट को सुरक्षित रखें ताकि क्रैश के बाद वर्कर्स फिर से काम शुरू कर सकें। एक बैकफ़िल एक अलग लक्षित पीढ़ी के तहत चलता है और वर्तमान पीढ़ी के साथ तुलना के बाद ही प्रकाशित होता है। पंक्ति संख्याओं, चेकसम, सैंपल किए गए समुच्चयों और वंशावली वॉटरमार्क की तुलना करें; जब कोई व्यू अपने पाँच मिनट के फ्रेशनेस लक्ष्य से अधिक हो जाता है या उसके पैरेंट असहमत होते हैं तो अलर्ट करें। एक आवधिक पूर्ण पुनर्निर्माण वृद्धिशील विचलन का पता लगाने के लिए एक ऑरेकल (oracle) प्रदान करता है।

एक मजबूत नमूना उत्तर

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

सामान्य गलतियाँ

  • प्रत्येक वंशज को तुरंत रिफ्रेश करना → बर्स्ट डुप्लिकेट कार्य उत्पन्न करते हैं → लक्षित वॉटरमार्क द्वारा इवेंट्स को संयोजित करें।
  • एकमात्र परिणाम को उसी स्थान पर अधिलेखित (overwrite) करना → एक विफल कार्य पाठकों को आंशिक डेटा के साथ छोड़ देता है → अपरिवर्तनीय पीढ़ियों को परमाणु रूप से प्रकाशित करें।
  • यह मान लेना कि प्रत्येक समुच्चय वृद्धिशील है → डिलीट या गैर-इनवर्टीबल फ़ंक्शन्स में विचलन होता है → एक क्वेरी-स्वरूप निर्णय नियम और पूर्ण पुनर्निर्माण फ़ॉलबैक का उपयोग करें।
  • पीढ़ी मेटाडेटा के बिना कैश करना → पैरेंट और चाइल्ड उत्तर असहमत हो सकते हैं → कैश कीज़ को एक पूर्ण पीढ़ी से बाइंड करें।
  • एक हॉट व्यू को सभी वर्कर्स का उपभोग करने देना → अन्य फ्रेशनेस SLOs विफल हो जाते हैं → प्रति-सोर्स और प्रति-व्यू समवर्ती सीमाओं का उपयोग करें।
  • प्रमाण के रूप में एक पंक्ति संख्या पर भरोसा करना → मूक विकृति (silent corruption) बची रहती है → चेकसम, सैंपल्स, वंशावली वॉटरमार्क और पूर्ण पुनर्निर्माण की तुलना करें।

फॉलो-अप प्रश्न और उत्तर

जब कोई चाइल्ड चल रहा हो और उसी समय एक पैरेंट व्यू रिफ्रेश हो जाए, तो क्या होगा?

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

डिलीट एक तथाकथित वृद्धिशील व्यू में आते हैं। क्या आप अभी भी डेल्टा रिफ्रेश का उपयोग कर सकते हैं?

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

आप बैकफ़िल को नए डेटा को बदलने से कैसे रोकते हैं?

बैकफ़िल को उसकी अपनी पीढ़ी और सोर्स वॉटरमार्क असाइन करें। केवल तभी प्रकाशित करें जब यह अनुरोधित रेंज को कवर करता हो और नए पार्टीशन्स को प्रतिस्थापित न करता हो; स्पष्ट रेंज और पीढ़ी के नियमों द्वारा मैनिफ़ेस्ट को मर्ज करें।

क्या होगा यदि व्यू को रिफ्रेश होने की तुलना में कहीं अधिक बार क्वेरी किया जाता है?

इसकी आयु के साथ अंतिम पूर्ण पीढ़ी को सर्व करें, फ्रेशनेस ऋण द्वारा इसे प्राथमिकता दें, और वैकल्पिक रूप से लोकप्रिय पैरामीटर कीज़ को पूर्व-परिकलित (precompute) करें। बासीपन को न छिपाएं या रीड मांग को रिफ्रेश समवर्ती सीमाओं को बायपास न करने दें।

सार्वजनिक स्रोत

संबंधित प्रश्न