प्रॉम्प्ट और यह कब लागू होता है
एक 64 GiB लिनक्स नोड में अभी भी 18 GiB MemAvailable उपलब्ध है, लेकिन एक कंटेनर छह घंटे के दौरान बार-बार एग्जिट होता है। रनटाइम OOMKilled और एग्जिट कोड 137 रिकॉर्ड करता है। वर्कलोड का cgroup v2 memory.max 4 GiB है; विफलता से पहले, memory.current उस लिमिट के करीब पहुँच जाता है और memory.events में oom_kill बढ़ जाता है। उसी अवधि के दौरान, memory.stat में anon 1.2 GiB से बढ़कर 3.5 GiB हो जाता है जबकि file लगभग 280 MiB रहता है। समझाइए कि आप ट्रिगर को कैसे साबित करेंगे, cgroup OOM और ग्लोबल OOM में कैसे अंतर करेंगे, वृद्धि के स्रोत का पता कैसे लगाएंगे, घटना को सुरक्षित रूप से कैसे नियंत्रित करेंगे, और इसे दोबारा होने से कैसे रोकेंगे।
64 GiB, 18 GiB, 4 GiB, छह घंटे की विंडो और उपयोग के आंकड़े इंटरव्यू के अनुमान हैं, कैपेसिटी बेंचमार्क नहीं। मान लें कि लिनक्स cgroup v2 का उपयोग करता है और रनटाइम स्थिति तथा cgroup फाइलें उसी विफलता विंडो को संदर्भित करती हैं। यह प्रश्न general से संबंधित है क्योंकि यह ऑपरेटिंग-सिस्टम रिक्लेम, cgroup अकाउंटिंग, OOM साक्ष्य और प्रोसेस हैंडलिंग का परीक्षण करता है; कंटेनर प्लेटफॉर्म केवल सेटिंग प्रदान करता है।
2026 में प्रकाशित सार्वजनिक लिनक्स और ऑपरेटिंग-सिस्टम इंटरव्यू सामग्री में सीधे OOM परिदृश्य शामिल हैं और उम्मीदवारों से कर्नेल लॉग, रिसोर्स लिमिट और प्रोसेस व्यवहार से निष्कर्ष निकालने के लिए कहा जाता है। एक संपूर्ण उत्तर केवल "मेमोरी जोड़ें" या "मैंने 137 देखा" से आगे का होना चाहिए: इसमें एक साक्ष्य श्रृंखला, सुरक्षित रोकथाम, स्रोत का पता लगाना, और एक प्रतिलिपि प्रस्तुत करने योग्य (reproducible) परीक्षण शामिल होना चाहिए जो यह दिखाए कि सुधार काम करता है।
इंटरव्यूअर क्या मूल्यांकन कर रहा है
पहला संकेत यह है कि क्या उम्मीदवार साक्ष्यों की सही व्याख्या करता है। Bash के एग्जिट-स्टेटस कन्वेंशन के तहत, 137 का अर्थ 128 प्लस सिग्नल 9 हो सकता है, इसलिए यह बताता है कि प्रोसेस SIGKILL के कारण समाप्त हुई। एक एडमिनिस्ट्रेटर, एक टाइमआउट कंट्रोलर, या OOM किलर सभी यह सिग्नल भेज सकते हैं। रनटाइम का OOMKilled कारण, उसी विंडो में memory.events:oom_kill में वृद्धि, और कर्नेल लॉग ही कारण को OOM तक सीमित करते हैं।
दूसरा संकेत यह है कि क्या उम्मीदवार रिसोर्स डोमेन की पहचान करता है। memory.max एक cgroup हार्ड लिमिट है। यदि उपयोग इस तक पहुँच जाता है और रिक्लेम चार्ज को कम नहीं कर पाता है, तो कर्नेल उस cgroup के अंदर OOM को इनवोक कर सकता है। नोड में फिर भी 18 GiB उपलब्ध हो सकता है। इसके विपरीत, एक ग्लोबल OOM नोड-व्यापी आवंटन दबाव से उत्पन्न होता है, जिसमें एक अलग विक्टिम पूल और अलग रिकवरी क्रियाएं होती हैं।
तीसरा संकेत मेमोरी-अकाउंटिंग अनुशासन है। केवल एक प्रोसेस के RSS को देखने से डिसेंडेंट्स (descendants), पेज कैश, tmpfs, शेयर्ड मेमोरी, सॉकेट बफ़र्स और उसी cgroup से चार्ज किया गया कर्नेल डेटा छूट जाता है। एक मजबूत उत्तर memory.current, memory.peak, memory.stat, प्रति-प्रोसेस मापों और एप्लिकेशन प्रोफाइल्स का मिलान करता है, न कि VSZ, RSS और cgroup चार्ज को समान मानता है।
अंत में, इंटरव्यूअर इंसिडेंट जजमेंट का मूल्यांकन कर रहा है। अस्थायी रूप से लिमिट बढ़ाने से सर्विस बहाल हो सकती है, या यह एक निरंतर लीक को नोड-व्यापी विफलता में बदल सकता है। उत्तर में यह स्पष्ट होना चाहिए कि लोड कब कम करना है, रीस्टार्ट करना है, स्केल करना है, या लिमिट बढ़ानी है; सामान्य पीक और लीक के बीच अंतर कैसे करना है; और लोड, सोक (soak) और विफलता परीक्षण नीति को कैसे मान्य करते हैं।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- क्या रिकॉर्ड उसी कंटेनर इंस्टेंस और विफलता विंडो को संदर्भित करते हैं? एक पुरानी
OOMKilledस्थिति, एक वर्तमान
cgroup काउंटर, और एक अलग एग्जिट एक कारण श्रृंखला (causal chain) नहीं बना सकते हैं। कंटेनर ID, प्रारंभ और एग्जिट समय, और पथ का मिलान करें।
- क्या होस्ट वास्तव में cgroup v2 का उपयोग कर रहा है? v1 और v2 विभिन्न फाइलों और सिमेंटिक्स को उजागर करते हैं। पुष्टि करें कि क्या पथ
कंटेनर का cgroup है या पैरेंट है जिसमें कई डिसेंडेंट वर्कलोड शामिल हैं।
- क्या
oom_killबदला या केवलoomबदला?oomबताता है कि लिमिट पूरी हो गई थी और एक आवंटन विफल होने वाला था;
oom_kill OOM किलर द्वारा वास्तव में मारे गए प्रोसेस को रिकॉर्ड करता है। memory.events.local के साथ पदानुक्रमित (hierarchical) गणनाओं की क्रॉस-जांच करें।
- क्या नोड ग्लोबल मेमोरी प्रेशर में भी था? कर्नेल लॉग्स,
MemAvailable, स्वैप, PSI, निष्कासन (eviction) इवेंट्स,
और आस-पास के वर्कलोड का निरीक्षण करें। cgroup OOM और नोड प्रेशर एक दूसरे के करीब हो सकते हैं।
- क्या 4 GiB की लिमिट कंटेनर, Pod, या पैरेंट cgroup की है? पैरेंट की लिमिट चाइल्ड की अपनी लिमिट तक पहुँचने से पहले ही
चाइल्ड को बाधित कर सकती है। पदानुक्रम को देखें और प्रत्येक प्रभावी सीमा का निरीक्षण करें।
- कौन सा वर्कलोड वृद्धि से संबंधित है? रिक्वेस्ट कन्करेंसी, कतार की गहराई, बैच साइज़, कैश कीज, कनेक्शन,
इनपुट साइज़, और परिनियोजन (deployment) संस्करण उस वर्किंग सेट को अलग करने में मदद करते हैं जो समय के साथ बढ़ने वाली रिटेंड मेमोरी से घटता है।
- cgroup को कितने प्रोसेस शेयर करते हैं? साइडकार्स, वर्कर्स, और स्पॉन किए गए चिल्ड्रन सभी चार्ज में योगदान करते हैं।
केवल मुख्य प्रोसेस की प्रोफाइलिंग करने से वृद्धि के वास्तविक ओनर की अनदेखी हो सकती है।
- रिकवरी और डेटा-इंटीग्रिटी आवश्यकताएं क्या हैं? मल्टीप्रोसेस वर्कलोड के एक सदस्य को किल करने से असंगत (inconsistent)
स्थिति छूट सकती है। रीस्टार्ट, लोड शेडिंग, ट्रैफिक शिफ्टिंग, और ग्रुप टर्मिनेशन आइडम्पोटेंसी और RTO पर निर्भर करते हैं।
30-सेकंड का उत्तर फ्रेमवर्क
“मैं 137 को SIGKILL का एक सुराग मानूँगा, OOM का निष्कर्ष नहीं। मैं कंटेनर ID और विफलता के समय का मिलान करूँगा, फिर रनटाइम के OOMKilled कारण, लक्षित cgroup के memory.events.local, memory.current, memory.max, और कर्नेल लॉग्स की जाँच करूँगा। नोड में फ्री मेमोरी है, लेकिन cgroup अपनी लिमिट तक पहुँच गया और oom_kill बढ़ गया, इसलिए साक्ष्य cgroup OOM की ओर इशारा करते हैं। मैं लोड को कम या शिफ्ट करूँगा और साक्ष्य को सुरक्षित रखूँगा, नोड हेडरूम की जाँच करने के बाद ही अस्थायी रूप से लिमिट बढ़ाऊँगा। फिर मैं memory.stat के साथ एनॉनिमस, फाइल, शेयर्ड और कर्नेल मेमोरी को अलग-अलग करूँगा, और प्रति-प्रोसेस प्रोफाइल को वर्कलोड मेट्रिक्स के साथ सहसंबंधित करूँगा ताकि लीक, अनबाउंड कैश, कन्करेंसी स्पाइक, या कम आकार की लिमिट को अलग किया जा सके। सुधार के बाद, मैं प्रतिनिधि पीक, लंबे सोक और नियंत्रित-लिमिट परीक्षण चलाऊँगा और memory.high, प्रेशर, पीक और OOM इवेंट्स पर अलर्ट सेट करूँगा।”
चरण-दर-चरण गहन विश्लेषण
पहला चरण: टर्मिनेशन को एक टाइमलाइन में बदलें।
कंटेनर ID, PID, प्रारंभ और एग्जिट समय, डिप्लॉयड संस्करण, रीस्टार्ट संख्या, और cgroup पथ रिकॉर्ड करें। एग्जिट 137 आमतौर पर शेल और कंटेनर स्थिति में SIGKILL से मेल खाता है, लेकिन यह OOM को साबित नहीं करता है: kill -9, एक प्लेटफॉर्म टाइमआउट, या एक नोड एजेंट समान परिणाम उत्पन्न कर सकता है। उसी सेकंड के आसपास reason: OOMKilled, cgroup इवेंट्स में डेल्टा, और कर्नेल संदेशों को सहसंबंधित करें।
memory.events.local को प्राथमिकता दें ताकि पैरेंट का पदानुक्रमित काउंटर डिसेंडेंट इवेंट्स को मिक्स न करे। यदि oom_kill इस एग्जिट पर 7 से बदलकर 8 हो जाता है, memory.current 4 GiB के करीब पहुँचता है, और कर्नेल लॉग एक मेमोरी-cgroup OOM की रिपोर्ट करता है, तो यह एक सुसंगत cgroup OOM श्रृंखला है। यदि केवल 137 है, जिसमें कोई काउंटर परिवर्तन या OOM रनटाइम कारण नहीं है, तो इसके बजाय मैनुअल सिग्नल, हेल्थ-चेक टाइमआउट, systemd-oomd, निष्कासन (eviction), और रनटाइम टर्मिनेशन की जांच करें।
दूसरा चरण: OOM रिसोर्स डोमेन की पहचान करें।
memory.max cgroup और उसके डिसेंडेंट्स के लिए अकाउंटेड मेमोरी को सीमित करता है। जब यह सीमा पूरी हो जाती है और डायरेक्ट रिक्लेम आवंटन को पूरा नहीं कर पाता है, तो कर्नेल केवल उस cgroup से विक्टिम चुन सकता है। इसलिए होस्ट का 18 GiB का MemAvailable कंटेनर की रक्षा नहीं करता है। उस सीमा को खोजने के लिए पैरेंट cgroups के माध्यम से ऊपर जाएँ जिसके memory.max और इवेंट काउंटर हिट हुए थे।
ग्लोबल OOM के अलग साक्ष्य होते हैं: नोड मेमोरी और स्वैप समाप्ति के करीब पहुँचते हैं, मेमोरी PSI बढ़ता है, कर्नेल लॉग में ग्लोबल मेमोरी स्थिति और एक विक्टिम शामिल होता है, और अन्य वर्कलोड प्रभावित होते हैं। नोड प्रेशर के तहत, प्लेटफॉर्म पहले Pod को निष्कासित कर सकता है। cgroup OOM को ठीक करना वर्कलोड उपयोग और उसकी लिमिट पर केंद्रित होता है; ग्लोबल OOM के लिए नोड ओवरकमिट, रिक्वेस्ट और रिजर्वेशन, सिस्टम डेमन्स, और वर्कलोड प्लेसमेंट को ठीक करने की भी आवश्यकता होती है।
तीसरा चरण: समझाएं कि 4 GiB कहाँ गया।
memory.current और memory.peak से शुरुआत करें, फिर memory.stat के साथ चार्ज को विभाजित करें। यहाँ, anon छह घंटों में 1.2 GiB से बढ़कर 3.5 GiB हो जाता है जबकि file लगभग 280 MiB रहता है। यह हीप्स, एनॉनिमस मैपिंग्स और उनके ओनर प्रोसेसेज को प्राथमिकता देता है, लेकिन यह अभी तक लीक को साबित नहीं करता है। कर्नेल प्रलेखन (documentation) कहता है कि cgroup अकाउंटिंग पेज कैश, tmpfs और शेयर्ड मेमोरी, कर्नेल स्ट्रक्चर्स, और सॉकेट बफ़र्स को भी कवर करती है; एक पैरेंट में डिसेंडेंट्स शामिल होते हैं।
कुल योग को प्रत्येक प्रोसेस के RSS, PSS, एनॉनिमस मैपिंग्स, प्रोसेस और थ्रेड काउंट्स, रनटाइम हीप मेट्रिक्स, और बिजनेस मापों के साथ एक टाइमलाइन पर रखें। यदि लाइव ऑब्जेक्ट्स और एप्लिकेशन हीप एक साथ बढ़ते हैं, तो रिटेंड रेफरेंसेस या अनबाउंडेड कैश की जांच करें। यदि हीप स्थिर है लेकिन RSS अधिक बना रहता है, तो एलोकेटर फ्रैग्मेंटेशन, नेटिव लाइब्रेरीज़, या mmap का निरीक्षण करें। file, shmem, sock, या slab में वृद्धि इसके बजाय tmpfs फाइलों, कैश, कनेक्शन बैकलॉग, या कर्नेल ऑब्जेक्ट्स की ओर इशारा करती है।
VSZ वर्चुअल एड्रेस स्पेस है, फिजिकल रेजिडेंसी या cgroup चार्ज नहीं। एक अकेला स्नैपशॉट भी अपर्याप्त है। एक स्वस्थ बैच वर्कलोड रिक्लेम के बाद पीक पर पहुँच सकता है और गिर सकता है; एक लीक आम तौर पर समान लोड पर बार-बार चक्रों में बेसलाइन को बढ़ाता है। समान थ्रूपुट पर स्लोप (ढलान) और रिलीज के बाद की स्थिर स्थिति की तुलना करें।
चौथा चरण: प्रत्येक परिकल्पना (hypothesis) को असत्य सिद्ध करने योग्य (falsifiable) बनाएं।
एक छोटी उम्मीदवार सूची रखें और प्रत्येक के लिए एक भविष्यवाणी बताएं। कन्करेंसी पीक के साथ, मेमोरी को इन-फ़्लाइट रिक्वेस्ट्स को ट्रैक करना चाहिए और उनके पूरा होने पर कम होना चाहिए। एक अनबाउंडेड कैश के साथ, एंट्री काउंट और anon एक साथ बढ़ते हैं और कैपेसिटी सीमित होने पर स्थिर हो जाते हैं। कंज्यूमर बैकलॉग के साथ, कतार की गहराई, बैच ऑब्जेक्ट्स और मेमोरी एक साथ चलते हैं। कम आकार की लिमिट के साथ, स्थिर प्रतिनिधि वर्किंग सेट ऊपर की ओर लंबी अवधि के स्लोप के बिना बार-बार सीमा के करीब पहुँचता है।
रनटाइम के लिए उपयुक्त हीप प्रोफाइल, एलोकेशन प्रोफाइल, या ऑब्जेक्ट हिस्टोग्राम का उपयोग करें, लेकिन कलेक्शन के ओवरहेड को ध्यान में रखें। कम जोखिम वाले प्रोडक्शन मेट्रिक्स या ट्रैफिक-शिफ्टेड रेप्लिकास के साथ शुरुआत करें; डंप लेने से पहले, डिस्क स्पेस, गोपनीयता और पॉज कॉस्ट की पुष्टि करें। वर्जन की तुलना या ट्रैफिक रीप्ले में एक समय में एक कारक बदलें। लिमिट बढ़ाना, कैश को डिसेबल करना, और कन्करेंसी को एक साथ कम करना मूल कारण को छुपा देगा।
पाँचवाँ चरण: रोकथाम को स्थायी सुधार से अलग करें।
पहले यूज़र्स और नोड को सुरक्षित करें: इंस्टेंस में कन्करेंसी को सीमित करें, मेमोरी-हैवी बैचों को रोकें, ट्रैफिक शिफ्ट करें, या ज्ञात-सुरक्षित संस्करण पर रोलबैक करें। यदि रीप्ले सुरक्षित है और मल्टीप्रोसेस स्थिति सुसंगत रहेगी, तो रीस्टार्ट जल्दी से मेमोरी को रिलीज कर देता है। यदि किसी एक वर्कर को किल करने से शेयर्ड स्टेट करप्ट हो जाती है, तो पूरे वर्कलोड को एक यूनिट के रूप में समाप्त करने पर विचार करें। cgroup v2 में, memory.oom.group=1 OOM किलर को cgroup को अविभाज्य (indivisible) मानने के लिए कहता है, लेकिन इसके रिकवरी सिमेंटिक्स का परीक्षण किया जाना चाहिए।
नोड हेडरूम, पड़ोसियों के लिए सुरक्षा, और अपेक्षित पीक को मापने के बाद ही memory.max को अस्थायी रूप से बढ़ाएं। एक समाप्ति समय (expiry), मॉनिटरिंग और रोलबैक थ्रेशोल्ड संलग्न करें। लगातार वृद्धि के लिए, एक बड़ी लिमिट केवल अगले OOM में देरी करती है। स्थायी सुधारों में कैश को सीमित करना, रेफरेंसेस रिलीज करना, बैचों और कन्करेंसी को सीमित करना, चाइल्ड-प्रोसेस लाइफसाइकल की मरम्मत करना, या मापे गए वर्किंग सेट और बर्स्ट भत्ते के आधार पर रिक्वेस्ट्स और लिमिट्स का आकार बदलना शामिल हो सकता है।
सामान्य सर्विस को oom_score_adj=-1000 असाइन करके इंसिडेंट को "हल" न करें। यह इसे OOM चयन से छूट देता है और कर्नेल को अधिक महत्वपूर्ण या अधिक संख्या में प्रोसेस को किल करने के लिए मजबूर कर सकता है; एंड-टू-एंड विफलता-नीति समीक्षा के बाद आवश्यक सिस्टम कार्यों के लिए इसे सुरक्षित रखें। स्वैप रिक्लेम और लेटेंसी व्यवहार को भी बदलता है। यह एक छोटे बर्स्ट को समाहित कर सकता है लेकिन असीमित वृद्धि को ठीक नहीं करता है।
छठा चरण: क्षमता को मान्य करें और पहले संकेत उत्पन्न करें।
प्रोडक्शन-समतुल्य cgroup अकाउंटिंग और लिमिट्स के तहत प्रतिनिधि ट्रैफिक को फिर से चलाएं (replay करें)। स्थिर लोड, पीक्स, बड़े इनपुट्स, बैकलॉग रिकवरी, और मल्टीप्रोसेस व्यवहार को कवर करें। पीक के लिए एक छोटे लोड टेस्ट, वृद्धि स्लोप और रिलीज के बाद की बेसलाइन के लिए एक लंबे सोक टेस्ट, और अलर्टिंग, टर्मिनेशन, रीस्टार्ट, और डेटा इंटीग्रिटी का अभ्यास करने के लिए एक नियंत्रित निचली लिमिट का उपयोग करें। सफलता का अर्थ है लक्षित थ्रूपुट और लेटेंसी पर परिभाषित हेडरूम, एक घटता हुआ memory.current, कोई नया oom_kill नहीं, और नोड प्रेशर या पड़ोसियों की स्थिति खराब न होना।
हार्ड लिमिट से पहले memory.high का उपयोग एक नियंत्रण सीमा के रूप में करें: इसे पार करने से cgroup थ्रॉटल होता है और OOM को सीधे इनवोक किए बिना डायरेक्ट रिक्लेम संचालित होता है, जिससे अलर्ट करने या रोकथाम को स्वचालित करने का समय मिलता है। memory.current/memory.max अनुपात, memory.peak, high, max, oom, और oom_kill इवेंट्स, मेमोरी PSI, रीस्टार्ट दर, एप्लिकेशन हीप और वृद्धि स्लोप की निगरानी करें। लिमिट्स पीक और सोक मापों से आनी चाहिए और संस्करणों, कन्करेंसी, या इनपुट वितरण में परिवर्तन होने पर उनकी समीक्षा की जानी चाहिए।
उच्च-गुणवत्ता वाला नमूना उत्तर
“मैं पहले यह साबित करूँगा कि क्या OOM के कारण यह टर्मिनेशन हुआ। एग्जिट 137 बताता है कि प्रोसेस को SIGKILL मिला; मैनुअल टर्मिनेशन और टाइमआउट भी ऐसा कर सकते हैं। मैं कंटेनर ID, एग्जिट टाइम और cgroup पाथ का मिलान करूँगा, फिर रनटाइम के OOMKilled कारण, memory.events.local में डेल्टा, और कर्नेल लॉग्स की जांच करूँगा। यदि oom_kill इस एग्जिट पर बढ़ा, memory.current 4 GiB को छू गया, और लॉग मेमोरी cgroup की पहचान करता है, तो यह cgroup OOM का समर्थन करता है।
यह यह भी स्पष्ट करता है कि नोड में 18 GiB उपलब्ध क्यों हो सकता है। memory.max cgroup की हार्ड बाउंड्री है, और विफल रिक्लेम कर्नेल को पहले होस्ट को समाप्त किए बिना उस रिसोर्स डोमेन के भीतर चयन करने के लिए मजबूर करता है। मैं समवर्ती नोड प्रेशर या प्लेटफॉर्म निष्कासन को बाहर करने के लिए पैरेंट cgroups, नोड PSI, स्वैप, और ग्लोबल OOM लॉग्स का भी निरीक्षण करूँगा।
रोकथाम के लिए, मैं मेमोरी-हैवी ट्रैफिक को कम या शिफ्ट करूँगा और विफलता से पहले के मेट्रिक्स और कम ओवरहेड वाली प्रोफाइल को सुरक्षित रखूँगा। यदि रीस्टार्ट सुरक्षित है, तो मैं एक ज्ञात संस्करण को पुनर्स्थापित करूँगा। मैं नोड हेडरूम और आस-पास के वर्कलोड की जांच करने के बाद ही समाप्ति और रोलबैक स्थिति के साथ अस्थायी रूप से लिमिट बढ़ाऊँगा। अधिक मेमोरी स्थायी समाधान नहीं है।
निदान के लिए, मैं memory.current, memory.peak, और memory.stat का उपयोग करके cgroup कुल का मिलान करूँगा, फिर प्रति प्रोसेस RSS, PSS, एनॉनिमस मैपिंग्स और रनटाइम हीप्स का निरीक्षण करूँगा। यहाँ anon 1.2 GiB से बढ़कर 3.5 GiB हो गया, जबकि फाइल मेमोरी लगभग 280 MiB थी, इसलिए मैं हीप, एनॉनिमस mmap, चाइल्ड प्रोसेस और एलोकेटर को प्राथमिकता दूँगा, लेकिन प्रोफाइल के साथ ओनर को साबित करूँगा। मैं मेमोरी को कन्करेंसी, कतार की गहराई, कैश एंट्रीज, बैच साइज और वर्जन के साथ सहसंबंधित करूँगा। समान लोड पर बढ़ता हुआ बेसलाइन एक लीक का सुझाव देता है; एक स्थिर वर्किंग सेट जो घटता है वह सामान्य पीक या कम लिमिट का सुझाव देता है।
सुधार के बाद, मैं उसी cgroup लिमिट के तहत पीक लोड और एक लंबा सोक टेस्ट चलाऊँगा, यह सत्यापित करते हुए कि मेमोरी कम हो रही है, इवेंट काउंटर्स बढ़ना बंद हो गए हैं, और लेटेंसी और थ्रूपुट लक्ष्यों को पूरा करते हैं। इसके बाद मैं हार्ड बाउंड्री से पहले memory.high और अलर्ट सेट करूँगा, पीक्स, प्रेशर, OOM इवेंट्स और वृद्धि स्लोप की निगरानी करूँगा, और मापे गए वर्किंग सेट से कन्करेंसी, कैश और कैपेसिटी का आकार तय करूँगा। मल्टीप्रोसेस सर्विस के लिए, मैं यह तय करने से पहले कि क्या OOM को पूरे ग्रुप को समाप्त करना चाहिए, आंशिक किल के बाद डेटा इंटीग्रिटी का भी परीक्षण करूँगा।”
सामान्य गलतियाँ
- केवल 137 से OOM घोषित करना →
SIGKILLऑपरेटर या टाइमआउट कंट्रोलर से आ सकता है → **रनटाइम
कारण, cgroup इवेंट्स और कर्नेल लॉग्स का मिलान करें।**
- OOM को खारिज करना क्योंकि होस्ट में फ्री मेमोरी है → नोड में हेडरूम होने पर भी cgroup अपनी हार्ड लिमिट को हिट कर सकता है →
पहले रिसोर्स डोमेन की पहचान करें।
- केवल एक प्रोसेस के RSS को देखना → डिसेंडेंट्स, फाइल्स, शेयर्ड मेमोरी, और कर्नेल चार्ज भी गिने जाते हैं → **कुल योग का
मिलान करें और memory.stat को ब्रेक डाउन करें।**
- VSZ को फिजिकल यूसेज मानना → एड्रेस-स्पेस साइज़ रेजिडेंसी या अकाउंटेड मेमोरी नहीं है → **RSS/PSS,
मैपिंग्स, और cgroup मेट्रिक्स की क्रॉस-जांच करें।**
- किसी भी
anonवृद्धि को लीक कहना → एक सामान्य वर्किंग सेट या बैच पीक भी बढ़ सकता है → **समान लोड पर
स्लोप्स और रिलीज के बाद की बेसलाइन की तुलना करें।**
- तुरंत लिमिट को दोगुना करना → यह लीक में देरी कर सकता है और नोड सेफ्टी मार्जिन का उपभोग कर सकता है → **कैपेसिटी
साक्ष्य, समाप्ति (expiry), और रोलबैक थ्रेशोल्ड की आवश्यकता रखें।**
- एप्लिकेशन को OOM से प्रतिरक्षित (immune) बनाना → नुकसान अन्य कार्यों या नोड पर शिफ्ट हो सकता है → **एंड-टू-एंड
विफलता नीति के हिस्से के रूप में ही oom_score_adj को बदलें।**
- केवल एक मिनट का लोड टेस्ट चलाना → एक छोटा टेस्ट धीमे लीक और फ्रैग्मेंटेशन को मिस कर देता है → **पीक और
लंबे सोक दोनों टेस्ट चलाएं।**
- केवल हार्ड लिमिट पर अलर्ट करना →
memory.maxपर प्रतिक्रिया देना आमतौर पर बहुत देर हो चुका होता है → **पहले
कार्रवाई के लिए memory.high, PSI, और वृद्धि स्लोप का उपयोग करें।**
- एक वर्कर के मरने के बाद रिकवरी मान लेना → मल्टीप्रोसेस शेयर्ड स्टेट असंगत हो सकती है → **ग्रुप
टर्मिनेशन, रीस्टार्ट, और डेटा-रिकवरी सिमेंटिक्स का परीक्षण करें।**
फॉलो-अप्स और प्रतिक्रिया कैसे दें
फॉलो-अप 1: एग्जिट कोड 137 मौजूद है, लेकिन oom_kill नहीं बढ़ा। आप आगे क्या जांच करेंगे?
पहले cgroup पाथ और इवेंट के समय की पुष्टि करें, और memory.events.local पढ़ें ताकि आप पैरेंट या नए इंस्टेंस की तुलना न करें। यदि OOM साक्ष्य अभी भी अनुपस्थित हैं, तो रनटाइम टर्मिनेशन कारण, डिप्लॉयमेंट या हेल्थ-चेक टाइमआउट, ऑपरेटर ऑडिट ट्रेल, systemd-oomd, नोड निष्कासन (eviction), और कर्नेल लॉग्स का निरीक्षण करें। एग्जिट 137 परिणाम को SIGKILL तक सीमित करता है; यह भेजने वाले की पहचान नहीं करता है।
फॉलो-अप 2: आप मेमोरी लीक और कम साइज वाली लिमिट के बीच अंतर कैसे करते हैं?
समान थ्रूपुट, इनपुट और कन्करेंसी पर बार-बार होने वाले चक्रों की तुलना करें। एक लीक आमतौर पर बेसलाइन या लाइव ऑब्जेक्ट काउंट को बढ़ाता है और कम लोड पर कम नहीं होता है। कम साइज वाली लिमिट के बार-बार पीक पर विफल होने और उसके बाद एक स्थिर वर्किंग सेट पर लौटने की अधिक संभावना होती है। हीप या एलोकेशन प्रोफाइल, कैश एंट्रीज, चाइल्ड प्रोसेस, बैच साइज़ और memory.stat के साथ मान्य करें; एक ग्राफ पर निर्भर न रहें। दोनों स्थितियां एक साथ मौजूद हो सकती हैं।
फॉलो-अप 3: memory.max बढ़ाना कब मान्य है?
इसे तब बढ़ाएं जब प्रतिनिधि पीक और सोक टेस्ट स्वस्थ व्यवहार दिखाते हैं जिसका आवश्यक वर्किंग सेट वर्तमान सीमा से अधिक है, जबकि नोड क्षमता, रिजर्वेशन, और पड़ोसी सुरक्षा अभी भी मार्जिन छोड़ते हैं। घटना के समय वृद्धि के लिए एक समाप्ति (expiry), मॉनिटरिंग और रोलबैक थ्रेशोल्ड की आवश्यकता होती है। यदि उपयोग बिना किसी सीमा के बढ़ता है, तो एक उच्च लिमिट केवल रोकथाम है; लोड को भी कम करें और वृद्धि के स्रोत को ठीक करें।
फॉलो-अप 4: memory.high और memory.max को एक साथ कैसे काम करना चाहिए?
memory.high एक थ्रॉटलिंग और डायरेक्ट-रिक्लेम सीमा है; इसे पार करने से OOM किलर सीधे इनवोक नहीं होता है, इसलिए यह एक अवलोकन और स्वचालन (automation) विंडो प्रदान कर सकता है। memory.max अंतिम अलगाव सीमा है और यदि रिक्लेम विफल हो जाता है तो यह cgroup OOM को इनवोक कर सकता है। दोनों को मापे गए वर्किंग सेट, पीक्स, लेटेंसी टॉलरेंस और नोड मार्जिन से सेट करें, और high, max, oom, और oom_kill इवेंट्स पर अलग से अलर्ट करें।
फॉलो-अप 5: एक मल्टीप्रोसेस सर्विस memory.oom.group का उपयोग क्यों कर सकती है?
यदि एक वर्कर को किल करने से असंगत शेयर्ड स्टेट, लॉक्स, या अधूरे लेनदेन छूट जाते हैं, तो cgroup को एक अविभाज्य (indivisible) वर्कलोड के रूप में मानने से विफलता और रिकवरी नियतात्मक (deterministic) हो सकती है। इसे सक्षम करने से पहले, पूरे ग्रुप के रीस्टार्ट समय, टास्क आइडम्पोटेंसी और डेटा रिकवरी का परीक्षण करें। oom_score_adj=-1000 वाले टास्क अपवाद हैं, इसलिए यह भी सत्यापित करें कि कोई आंशिक वर्कलोड शेष न रहे।