प्रॉम्प्ट और संदर्भ
एक प्लेटफ़ॉर्म टीम को पता चलता है कि पीक के दौरान किसी टेनेंट का बैच कंटेनर ऑनलाइन सेवाओं पर दबाव डाल सकता है। नोड cgroup v2 का उपयोग करता है, लेकिन टीम ने केवल एक मेमोरी लिमिट सेट की है और वह रिक्लेम (reclaim), थ्रॉटलिंग (throttling), और टर्मिनेशन (termination) के बीच अंतर नहीं कर पा रही है। सुरक्षा सीमाओं, इवेंट मॉनिटरिंग और रोलबैक के साथ एक लेयर्ड मेमोरी पॉलिसी डिज़ाइन करें।
इंटरव्यूअर क्या जांच रहा है
- क्या आप memory.min/low सुरक्षा को memory.high रिक्लेम/थ्रॉटलिंग और memory.max प्रवर्तन से अलग करते हैं।
- क्या आप पदानुक्रमित (hierarchical) memory.events और स्थानीय memory.events.local को समझते हैं।
- क्या आप OOM ग्रुप किलिंग, चाइल्ड cgroups, बर्स्ट्स (bursts), और ओवरकमिट को संभालते हैं।
- क्या आप कर्नेल फ़ाइलों को ऑर्केस्ट्रेशन, अलर्ट्स और ड्रिल्स से जोड़ सकते हैं।
पहले पूछे जाने वाले स्पष्टीकरण प्रश्न
- क्या आप महत्वपूर्ण वर्कलोड्स की सुरक्षा कर रहे हैं, किसी टेनेंट को सीमित कर रहे हैं, या पूरे नोड की सुरक्षा कर रहे हैं?
- क्या वर्कलोड लेटेंसी-सेंसिटिव है, बैच-उन्मुख है, या इसे रिक्लेम और पुनः प्रयास (retry) करना सुरक्षित है?
- cgroup पदानुक्रम (hierarchy) क्या है, और क्या पैरेंट ग्रुप्स में साइडकार शामिल हैं?
- क्या Kubernetes वर्कलोड को प्रबंधित करता है, और requests व limits cgroup v2 में कैसे मैप होते हैं?
- क्या OOM को एक प्रोसेस को किल करना चाहिए, पूरे cgroup को किल करना चाहिए, या कंट्रोलर द्वारा कंटेनर को फिर से बनाना चाहिए?
30-सेकंड का उत्तर ढांचा
सुरक्षा स्तरों के लिए memory.min और memory.low का उपयोग करें, प्रारंभिक रिक्लेम और थ्रॉटलिंग सीमा के लिए memory.high का उपयोग करें, और अंतिम हार्ड लिमिट के रूप में memory.max का उपयोग करें। memory.oom.group यह निर्धारित करता है कि OOM हैंडलिंग ग्रुप-व्यापी है या नहीं। नोड से टेनेंट और वर्कलोड तक बजट आवंटित करें, memory.current, memory.events, और PSI की निगरानी करें, और कैनरी, दबाव परीक्षण (pressure tests), व रोलबैक के साथ सत्यापित करें। Kubernetes में, केवल YAML पर भरोसा करने के बजाय रेंडरिंग के बाद वास्तविक cgroup फ़ाइलों को पढ़ें।
चरण-दर-चरण गहन उत्तर
चरण 1: सिमेंटिक मॉडल का निर्माण करें
memory.min एक हार्ड सुरक्षा सीमा है जिसके उपयोग को केवल अत्यधिक दबाव में ही रिक्लेम किया जाता है; memory.low एक बेस्ट-एफ़र्ट सुरक्षा है जिसे गंभीर दबाव में रिक्लेम किया जा सकता है। memory.high रिक्लेम और थ्रॉटलिंग को ट्रिगर करता है लेकिन सीधे OOM किलर को इनवोक नहीं करता है। memory.max एक ऐसी सीमा है जिसे पार नहीं किया जा सकता, जो cgroup OOM में जा सकती है जब रिक्लेम इसे संतुष्ट नहीं कर पाता।
चरण 2: पैरेंट और चाइल्ड बजट आवंटित करें
सिस्टम और महत्वपूर्ण सेवाओं के लिए नोड क्षमता आरक्षित करें, प्रत्येक टेनेंट पैरेंट को एक सीलिंग (अधिकतम सीमा) सौंपें, फिर ऑनलाइन, बैच और साइडकार वर्कलोड्स के लिए चाइल्ड ग्रुप्स सेट करें। चाइल्ड सुरक्षा बिना शर्त पैरेंट के उपलब्ध बजट से अधिक नहीं हो सकती। प्रत्येक स्तर के वर्तमान उपयोग, इवेंट्स और पॉलिसी संस्करण को रिकॉर्ड करें। बर्स्ट्स के लिए high के नीचे हेडरूम छोड़ें ताकि एक छोटा स्पाइक तुरंत max OOM न बन जाए।
चरण 3: high-to-max संबंध चुनें
memory.high कर्नेल को पहले रिक्लेम और थ्रॉटलिंग लागू करने देता है; लेटेंसी, थ्रूपुट और इवेंट्स का अवलोकन करने के बाद एप्लिकेशन धीमा हो सकता है। memory.max अंतिम सुरक्षा वाल्व है और इसे पुनर्प्राप्ति क्षमता (recoverability) को दर्शाना चाहिए। बहुत कम high क्रोनिक थ्रॉटलिंग का कारण बनता है, जबकि बहुत अधिक max पैरेंट या नोड पर दबाव स्थानांतरित कर देता है। लोड टेस्ट्स के साथ दोनों को कैलिब्रेट करें।
चरण 4: OOM ग्रुप पॉलिसी तय करें
निकटता से जुड़े (tightly coupled) प्रोसेस के लिए, memory.oom.group=1 OOM हैंडलिंग को ग्रुप-व्यापी बनाता है ताकि केवल मुख्य प्रोसेस के किल होने के बाद कोई हेल्पर प्रोसेस पीछे न छूटे। स्वतंत्र बैच जॉब्स यह प्राथमिकता दे सकते हैं कि एक प्रोसेस बाहर निकले और एक कतार इसे फिर से आज़माए। किसी भी विकल्प के लिए एग्जिट कारण, रीस्टार्ट्स और अधूरे काम को रिकॉर्ड करें; OOM कोई अदृश्य पुनः प्रयास नहीं है।
चरण 5: memory.events की निगरानी करें
memory.events पदानुक्रमित (hierarchical) है, इसलिए चाइल्ड इवेंट्स पैरेंट में दिखाई दे सकते हैं; memory.events.local केवल स्थानीय इवेंट्स की रिपोर्ट करता है। high, max, oom, और oom_kill के डेल्टास (deltas) की निगरानी करें, जो memory.current, वर्किंग सेट, PSI, लेटेंसी और कतार की आयु (queue age) से सहसंबंधित हों। फ़ाइल क्रम पर निर्भर रहने के बजाय कीज़ (keys) को पार्स करें क्योंकि नई कीज़ दिखाई दे सकती हैं।
चरण 6: पॉलिसी को ऑर्केस्ट्रेशन में मैप करें
Kubernetes पर, requests, limits, QoS, और नोड के cgroup मोड का एक साथ निरीक्षण करें। रेंडरिंग के बाद, कंटेनर में प्रवेश करें और वास्तविक मानों को सत्यापित करने के लिए /sys/fs/cgroup पढ़ें ताकि यह सुनिश्चित हो सके कि रनटाइम ने उन्हें ओवरराइड नहीं किया है। साइडकार, init कंटेनर और साझा emptyDir एकाउंटिंग की जाँच करें; एक चाइल्ड स्वस्थ दिख सकता है जबकि उसका पैरेंट high या max तक पहुँच जाता है।
चरण 7: ड्रिल, रिलीज़ और रोल बैक करें
सिंगल-नोड कैनरी पर, high को धीरे-धीरे कम करें और रिक्लेम व थ्रॉटलिंग का निरीक्षण करें, फिर max और oom.group टर्मिनेशन का परीक्षण करें। निरंतर high, पहले max, और वास्तविक oom_kill पर अलग से अलर्ट करें। पिछले संस्करण और इवेंट स्नैपशॉट के साथ संस्करणबद्ध (versioned) पॉलिसियों को प्रकाशित करें। पहले बजट को रोल बैक करें, फिर किल किए गए जॉब्स और कतार पुनः प्रयासों को रीकॉन्साइल करें ताकि नोड पर कोई दबाव न रहे।
उच्च-गुणवत्ता वाला नमूना उत्तर
सुरक्षा के लिए min और low का उपयोग करें, अवलोकनीय रिक्लेम और थ्रॉटलिंग के लिए high का उपयोग करें, और अंतिम हार्ड सीमा के रूप में max का उपयोग करें। पैरेंट-चाइल्ड पदानुक्रम के माध्यम से नोड, टेनेंट और वर्कलोड बजट आवंटित करें, फिर पुनर्प्राप्ति क्षमता के आधार पर oom.group चुनें। PSI, लेटेंसी, कतार की आयु और रीस्टार्ट्स के साथ पदानुक्रमित बनाम स्थानीय memory.events की निगरानी करें। Kubernetes में, रेंडर की गई cgroup फ़ाइलों को सत्यापित करें। कैनरी और दबाव ड्रिल के साथ रोल आउट करें, और एक संस्करणबद्ध रोलबैक पॉलिसी बनाए रखें।
सामान्य गलतियाँ
- memory.high को तत्काल OOM सीमा के रूप में मानना।
- memory.low को कभी न टूटने वाली गारंटी के रूप में मानना।
- रनटाइम cgroup फ़ाइलों को पढ़े बिना कंटेनर YAML पर भरोसा करना।
- पैरेंट के पदानुक्रमित इवेंट्स को स्थानीय इवेंट्स के साथ मिलाना।
- आइडेम्पोटेंसी, आंशिक कार्य, और पुनः प्रयास के तूफानों (retry storms) की जाँच किए बिना OOM के बाद रीस्टार्ट करना।
फॉलो-अप प्रश्न और उत्तर
फॉलो-अप 1: memory.high पार होने के बाद क्या होता है?
कर्नेल रिक्लेम और थ्रॉटलिंग दबाव लागू करता है। प्रोसेस जारी रह सकते हैं लेकिन लेटेंसी बढ़ सकती है। यह OOM-killer स्विच नहीं है; high काउंटर को PSI और सर्विस लेटेंसी के साथ सहसंबंधित करें।
फॉलो-अप 2: यदि high मौजूद है तो memory.max को क्यों रखें?
High किसी वर्कलोड को दबाव में संसाधन छोड़ने की अनुमति देता है, जबकि max उस वृद्धि को रोकता है जिसे रिक्लेम नहीं किया जा सकता और पैरेंट या नोड की सुरक्षा करता है। Max को पुनर्प्राप्ति क्षमता और रीस्टार्ट पॉलिसी को ध्यान में रखकर डिज़ाइन किया जाना चाहिए।
फॉलो-अप 3: memory.events किसी इवेंट को दो बार गिनता हुआ क्यों प्रतीत हो सकता है?
पैरेंट memory.events में डिफ़ॉल्ट रूप से सब-ट्री इवेंट्स शामिल होते हैं, जबकि memory.events.local उस cgroup के लिए स्थानीय होता है। प्रत्येक अलर्ट के लिए एक स्तर चुनें और पदानुक्रम द्वारा डिडुप्लिकेट करें।
फॉलो-अप 4: memory.oom.group को कब सक्षम किया जाना चाहिए?
इसे तब सक्षम करें जब एक cgroup के सभी प्रोसेस को एक साथ चलना और फिर से शुरू होना चाहिए। स्वतंत्र कार्य व्यक्तिगत रूप से समाप्त हो सकते हैं। दोनों विकल्पों के लिए क्लीनअप, पुनः प्रयास और अवलोकनीयता परीक्षणों की आवश्यकता होती है।
फॉलो-अप 5: आप कैसे साबित करेंगे कि Kubernetes मैपिंग सही है?
लक्षित नोड पर, कंटेनर cgroup के लिए memory.min, memory.low, memory.high, memory.max, और events पढ़ें। उनकी तुलना रेंडर किए गए requests, limits, QoS, और रनटाइम सेटिंग्स से करें, फिर एक दबाव ड्रिल चलाएं।