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

सिस्टम डिज़ाइन इंटरव्यू: पुराने (Stale) Kubernetes कंट्रोलर कैश को संभालना

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

प्रश्न

ओवरलोड या रीस्टार्ट के बाद एक Kubernetes कंट्रोलर पुराने कैश डेटा पर कार्य कर सकता है। पूरे कंट्रोलर को ब्लॉक किए बिना डिटेक्शन, स्किप-एंड-रीक्यू (skip-and-requeue) व्यवहार और ऑब्जर्वेबिलिटी डिज़ाइन करें।

प्रॉम्प्ट और संदर्भ

एक Kubernetes कंट्रोलर Informer कैश से ऑब्जेक्ट्स को पढ़ता है और वांछित स्थिति (desired state) को API सर्वर पर लिखता है। लोड, वॉच डिले या रीस्टार्ट के तहत कैश API सर्वर से पीछे छूट सकता है; कंट्रोलर बार-बार राइट्स दोहरा सकता है, गलत तरीके से स्केल कर सकता है, या किसी पुराने Lease को समाप्त (expired) मान सकता है। ऐसा स्टेटेलनेस डिटेक्शन और मिटिगेशन डिज़ाइन करें जो केवल प्रभावित ऑब्जेक्ट्स को ब्लॉक करे।

यह प्लेटफ़ॉर्म इंजीनियरिंग, SRE और क्लाउड-नेटिव कंट्रोलर भूमिकाओं के लिए प्रासंगिक है। Kubernetes v1.36 और KEP 5647 में AtomicFIFO, LastStoreSyncResourceVersion(), राइट्स के रिसोर्स वर्ज़न को ट्रैक करने, पुराने कीज़ को छोड़ने और फिर से कतारबद्ध करने (skipping and re-queuing), और DaemonSet, StatefulSet, ReplicaSet, तथा Job कंट्रोलर्स को ऑनबोर्ड करने का वर्णन किया गया है। यह एक सार्वजनिक-स्रोत डिज़ाइन अभ्यास है, किसी कंपनी के इंटरव्यू बैंक का दावा नहीं।

इंटरव्यूअर क्या मूल्यांकन करता है

इंटरव्यूअर यह देखना चाहता है कि क्या आप इवेंचुअली कंसिस्टेंट कैश की सीमाओं को समझते हैं और "पर्याप्त रूप से ताज़ा" (fresh enough) को एक परीक्षण-योग्य रिसोर्स-वर्ज़न शर्त में बदल सकते हैं। एक मजबूत उत्तर में कैश सिंक, रीड-आफ्टर-राइट, प्रति-की कतारें, बैकऑफ़, रीस्टार्ट, मॉनिटरिंग और फीचर गेट्स शामिल होते हैं। एक कमजोर उत्तर प्रत्येक रिकॉन्साइल कॉल को सीधे API सर्वर पर भेजता है और लोड व कंसिस्टेंसी लागत को नजरअंदाज करता है।

स्पष्टीकरण के लिए प्रश्न

  • कौन से निर्णय विनाशकारी (destructive) हैं: Pods को हटाना, स्केल डाउन करना, लीडर बदलना, या सामान्य स्टेटस अपडेट?
  • कितना पुराना विंडो स्वीकार्य है, और क्या कोई महत्वपूर्ण ऑपरेशन एक बार API-सर्वर रीड का खर्च उठा सकता है?
  • क्या हमें एक ऑब्जेक्ट के लिए रीड-आफ्टर-राइट की आवश्यकता है या कई ऑब्जेक्ट्स में कॉज़ल ऑर्डरिंग की?
  • रीस्टार्ट, वॉच रीकनेक्ट या API-सर्वर विफलता के बाद, क्या कंट्रोलर को रूढ़िवादी तरीके से प्रतीक्षा करनी चाहिए या सीमित गिरावट (bounded degradation) की अनुमति देनी चाहिए?

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

“मैं Informer कैश को डिफ़ॉल्ट रीड पाथ के रूप में रखूँगा और प्रगति को मापने के लिए AtomicFIFO के साथ नवीनतम प्रेक्षित (observed) रिसोर्स वर्ज़न का उपयोग करूँगा। किसी महत्वपूर्ण ऑब्जेक्ट को लिखने के बाद, कंट्रोलर उसके लक्षित वर्ज़न को रिकॉर्ड करता है; जब तक कैश उस स्तर तक नहीं पहुँच जाता, वह केवल उसी की (key) को छोड़ता है और एक्सपोनेंशियल बैकऑफ़ के साथ फिर से कतारबद्ध करता है। विनाशकारी कार्रवाइयों के लिए एक सीमित लाइव रीड या सर्किट ब्रेकर जोड़ा जाता है। मेट्रिक्स कैश लैग, स्किप किए गए रिकॉन्साइल्स और कतार की आयु को उजागर करते हैं। रीस्टार्ट पर, सुरक्षा को बनाए रखें, कैश सिंक पूरा करें, और फिर काम शुरू करें।”

चरण-दर-चरण समाधान

पहले स्टेलनेस को परिभाषित करें। एक Informer Store वॉच इवेंट्स द्वारा भरा जाता है, जो कैश पुनर्निर्माण के दौरान विलंबित, पुनर्व्यवस्थित या अस्थायी रूप से अधूरे हो सकते हैं। Kubernetes v1.36 का AtomicFIFO इनिशियल लिस्ट बैच को इंक्रीमेंटल इवेंट्स के सापेक्ष एटॉमिक बनाता है, जिससे उन्हें आपस में मिलाने से होने वाले असंगत कैश से बचा जा सकता है। LastStoreSyncResourceVersion() Store द्वारा देखे गए नवीनतम वर्ज़न को प्रदर्शित करता है।

प्रत्येक महत्वपूर्ण राइट के लिए, objectKey -> resourceVersion बनाए रखें। जब कोई DaemonSet किसी Pod को अपडेट करता है, तो API सर्वर द्वारा लौटाए गए वर्ज़न को रिकॉर्ड करें। प्रत्येक Pod इन्फॉर्मर इवेंट उच्चतम प्रेक्षित वर्ज़न को आगे बढ़ाता है। DaemonSet नई स्थिति पर निर्भर अगले रिकॉन्साइल को केवल तभी चला सकता है जब प्रेक्षित वर्ज़न अंतिम राइट तक पहुँच जाए। अन्यथा उस की (key) को सामान्य एक्सपोनेंशियल बैकऑफ़ के साथ फिर से कतारबद्ध करें; पूरे वर्कर पूल को कभी न रोकें।

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

समय-संवेदनशील निर्णयों के लिए, एक सर्किट ब्रेकर जोड़ें। फ़ास्ट पाथ के लिए कैश का उपयोग करें; जब लक्षित वर्ज़न अज्ञात हो या लैग किसी सीमा से अधिक हो, तो API सर्वर से एक सीमित लाइव रीड करें। यदि यह विफल हो जाता है, तो केवल उस की को रोकें और कारण रिकॉर्ड करें। लाइव रीड्स को डिफ़ॉल्ट बनाने से API-सर्वर QPS, लेटेंसी और विफलता का दायरा बढ़ जाएगा।

प्रति कंट्रोलर इन्फॉर्मर रिसोर्स वर्ज़न, टारगेट राइट वर्ज़न, लैग की अवधि, छोड़े गए रिकॉन्साइल की संख्या, कतार की आयु, लाइव-रीड सफलता दर और सर्किट-ब्रेकर काउंट को प्रदर्शित करें। लॉग्स में ऑब्जेक्ट की, वर्ज़न और कार्रवाई शामिल होती है, कभी भी Secret मान नहीं। अलर्ट API-सर्वर के धीमेपन, टूटे हुए वॉचेस, हॉट की (hot key) और धीमे कंट्रोलर प्रोसेसिंग के बीच अंतर करते हैं।

इसे फ़ीचर गेट और कैनरी के पीछे रिलीज़ करें। इसे एक उच्च-प्रतिस्पर्धा वाले कंट्रोलर और एक छोटे नोड पूल के लिए सक्षम करें, फिर स्किपिंग के बाद कन्वर्जेंस, रीस्टार्ट रिकवरी, और कतार में भुखमरी (starvation) की अनुपस्थिति की पुष्टि करें। API-सर्वर लोड स्वीकार्य होने के बाद ही विस्तार करें। मेट्रिक्स और ऑब्जेक्ट स्थिति को बनाए रखते हुए नए कंसिस्टेंसी पाथ को अक्षम करके रोलबैक करें; सुरक्षा मैपिंग को थोक में न हटाएं।

मॉडल उत्तर

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

डिलीट्स, स्केल-डाउन और Lease निर्णय एक सीमित लाइव रीड का उपयोग करते हैं जब कैश की ताजगी अज्ञात होती है या सीमा से ऊपर होती है; विफलता उस की को रोक देती है। मेट्रिक्स वर्ज़न लैग, छोड़े गए कार्य, कतार की आयु और लाइव-रीड अनुपात को कवर करते हैं। मैपिंग को पुनर्स्थापित करने से पहले रीस्टार्ट कैश सिंक की प्रतीक्षा करता है। कैनरी रोलआउट कन्वर्जेंस, रिकवरी और API-सर्वर लोड को मान्य करता है; सुरक्षा स्थिति कभी भी विश्व स्तर पर साफ़ नहीं की जाती है।

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

  • गलती → हर रिकॉन्साइल पर API सर्वर को लाइव-रीड करना; यह क्यों विफल होता है → QPS और लेटेंसी बढ़ जाती है और कैश का उद्देश्य समाप्त हो जाता है; सुधार → केवल महत्वपूर्ण कार्रवाइयों या अज्ञात वर्ज़न के लिए लाइव-रीड करें।
  • गलती → जब एक ऑब्जेक्ट पुराना हो तो प्रत्येक वर्कर को रोक देना; यह क्यों विफल होता है → एक हॉट की वैश्विक आउटेज पैदा करती है; सुधार → ऑब्जेक्ट की के अनुसार छोड़ें और फिर से कतारबद्ध करें।
  • गलती → केवल स्थानीय टाइमस्टैम्प की तुलना करना; यह क्यों विफल होता है → क्लॉक ड्रिफ्ट वॉच कॉज़ैलिटी साबित नहीं कर सकता; सुधार → API रिसोर्स वर्ज़न की तुलना करें।
  • गलती → रीस्टार्ट के बाद सभी सुरक्षा हटा देना; यह क्यों विफल होता है → कैश पुनर्निर्माण के दौरान निर्णय निष्पादित हो सकते हैं; सुधार → सिंक की प्रतीक्षा करें और वर्ज़न जाँच के साथ स्थिति बहाल करें।

फॉलो-अप प्रश्न

स्थानीय टाइमस्टैम्प की तुलना में रिसोर्स वर्ज़न अधिक सुरक्षित क्यों है?

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

जब कोई एक की (key) पुरानी बनी रहती है तो आप भुखमरी (starvation) से कैसे बचते हैं?

अन्य कीज़ को चलने की अनुमति देते हुए एक्सपोनेंशियल बैकऑफ़ को सीमित करें और अधिकतम प्रतीक्षा समय पर अलर्ट करें। सीमा पार होने के बाद, कम आवृत्ति वाली प्रोबिंग या एक लाइव रीड पर स्विच करें। लगातार छोड़े जाने (consecutive skips) की गिनती करें ताकि तेज़ पुनः प्रयास API सर्वर को ओवरलोड न कर सकें।

किसी ऑपरेशन को कब अस्वीकार किया जाना चाहिए?

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

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

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

संबंधित इंटरव्यू टूल

सिस्टम डिज़ाइन उत्तर के लिए हल करें का उपयोग करें

पहले आवश्यकताओं को स्पष्ट करें, फिर स्केल, आर्किटेक्चर, कंपोनेंट चयन और ट्रेड-ऑफ की ओर बढ़ें।

टूल देखें