Vm.overcommit_memory को कॉन्फ़िगर करने के प्रभाव


41

CentOS 5.4 (लिनक्स कर्नेल 2.6.16.33-xenU) पर चलने वाला मेरा वीपीएस वेब सर्वर अनियमित रूप से (जैसे महीने में एक बार कुछ सप्ताह देते हैं या लेते हैं) ओओम-किलर किकिंग के कारण अनुत्तरदायी हो जाता है। सर्वर की निगरानी से पता चलता है कि यह नहीं है। आम तौर पर स्मृति से बाहर चला जाता है, बस हर बार।

मैंने इस पृष्ठ पर इंगित करने वाले कुछ ब्लॉगों को पढ़ा है, जो कर्नेल को निम्नलिखित sysctive सेटिंग्स का उपयोग करके बेहतर तरीके से प्रबंधित करने के लिए कॉन्फ़िगर करने पर चर्चा करता है:

vm.overcommit_memory = 2
vm.overcommit_ratio = 80

इस बारे में मेरी समझ (जो गलत हो सकती है, लेकिन मैं स्पष्ट करने के लिए एक विहित परिभाषा नहीं ढूंढ सकता हूं) यह है कि यह कर्नेल को भौतिक स्मृति से + 80% से परे स्मृति को आवंटित करने से रोकता है।

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

तो मेरा प्रश्न यह है कि अपाचे 2 वेब सर्वर के संदर्भ में 10 निम्न यातायात साइटों की मेजबानी के संदर्भ में इस दृष्टिकोण के पेशेवरों और विपक्ष क्या हैं ? मेरे विशिष्ट मामले में, वेब सर्वर में 512Mb रैम है, जिसमें 1024Mb स्वैप स्पेस है। यह अधिकांश समय के लिए पर्याप्त लगता है।

जवाबों:


32

overcommit_ratio80 पर सेट करना सही कार्रवाई नहीं है। 100 से कम किसी भी चीज़ के लिए मूल्य निर्धारित करना लगभग हमेशा गलत होता है।

इसका कारण यह है कि लिनक्स के अनुप्रयोगों को वास्तव में आवश्यकता से अधिक आवंटित किया जाता है। कहते हैं कि वे पाठ के एक जोड़े चरित्र स्ट्रिंग को संग्रहीत करने के लिए 8kb आवंटित करते हैं। अच्छी तरह से कई KB ठीक वहाँ अप्रयुक्त। अनुप्रयोग इसे बहुत कुछ करते हैं, और यह वही है जिसके लिए ओवरकमिट को डिज़ाइन किया गया है।

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

अब, OOM हत्यारा ट्रिगर के साथ अपने मुद्दे के लिए के रूप में, मैन्युअल रूप से overcommit सेटिंग यह निश्चित रूप से ठीक नहीं होगा। डिफ़ॉल्ट सेटिंग (ह्यूरिस्टिक निर्धारण) काफी बुद्धिमान है।

यदि आप यह देखना चाहते हैं कि क्या यह वास्तव में इस मुद्दे का कारण है, /proc/meminfoतो देखें कि OOM हत्यारा कब चलता है। यदि आप देखते हैं कि Committed_ASयह करीब है CommitLimit, लेकिन freeफिर भी उपलब्ध मुफ्त मेमोरी दिखा रहा है, तो हाँ आप अपने परिदृश्य के लिए मैन्युअल रूप से ओवरकाम को समायोजित कर सकते हैं। इस मान को बहुत कम सेट करने से OOM किलर को मारना शुरू हो जाएगा जब आप अभी भी बहुत सारे मेमोरी फ्री हैं। इसे बहुत अधिक सेट करने से यादृच्छिक अनुप्रयोग मर सकते हैं जब वे स्मृति का उपयोग करने की कोशिश करते हैं जो उन्हें आवंटित किया गया था, लेकिन वास्तव में उपलब्ध नहीं है (जब सभी मेमोरी वास्तव में उपयोग हो जाती है)।


1
धन्यवाद - मैं देख रहा हूँ कि क्या होता है overcommit_ratio के साथ 100 कोशिश करते हैं कि क्या होता है। मेरे पास मुख्य समस्या यह है कि जब ऊम-किलर शुरू होता है, तो यह हमेशा के लिए sshd को मारता है जो मुझे सर्वर तक पहुंचने से रोकता है और देखता है कि क्या चल रहा है। मुझे लगता है कि मुझे वास्तव में ओमे-किलर को चलाने से रोकने की आवश्यकता है और रिकॉर्डिंग के कुछ साधनों का क्या होता है जब यह चलता है तो मुझे समस्या का कारण मिल सकता है।
dunxd

4
@dunxd आप /proc/<PID>/oom_score_adjइस उद्देश्य के लिए उपयोग कर सकते हैं । उदाहरण के लिए, यदि आप sshd के लिए oom_score_adj से -1000 सेट करते हैं, तो oom हत्यारा कभी भी sshd को लक्षित नहीं करेगा जब वह कुछ मारना चाहता है। ऑम किलर को पूरी तरह से रोकना एक अच्छा विचार नहीं है क्योंकि तब तक आपके प्रोग्राम मैलोक मेमोरी में सक्षम नहीं होंगे, और वे वैसे भी मर जाएंगे।
पैट्रिक

4
@dunxd को विरासत में मिला है। अपने init स्क्रिप्ट को खुद पर सेट करें, और init स्क्रिप्ट द्वारा शुरू किया गया कुछ भी इसे विरासत में मिला है।
पैट्रिक

4
आपका 4 KB का उदाहरण गलत है। वर्चुअल मेमोरी का उपयोग पृष्ठों के साथ किया जाता है और लिनक्स के तहत एक पृष्ठ का (सबसे छोटा) आकार 4 KB है। इसका मतलब है कि कुछ पात्रों को संग्रहीत करने के लिए 4 केबी की आवश्यकता होती है, जिसे ओवरकमिटमेंट सेटिंग्स की परवाह किए बिना कहीं और मैप किया जाना चाहिए। प्रतिबद्धता पर स्मृति का एक उचित उदाहरण होगा उदाहरण के लिए आप 10 केबी आवंटित करते हैं और केवल पहले 4100 बाइट्स का उपयोग करते हैं। इसका अर्थ है कि डेटा को संग्रहीत करने के लिए दो 4 KB पृष्ठों की आवश्यकता है और एक अतिरिक्त पृष्ठ अप्रयुक्त है। नॉन ओवरकमिंग सिस्टम में हमेशा यह होगा कि डेटा स्टोर करने के लिए तैयार तीसरा पेज आने चाहिए, कमिटिंग सिस्टम उस पर लागू नहीं होगा।
जुलियाग्रे

2
वर्तमान प्रक्रिया के लिए / proc / self अंक, इसलिए / proc / self / oom_score_adj का उपयोग वर्तमान प्रक्रिया के oom_score_adj को बदलने के लिए किया जा सकता है।
r_2

23

डॉक्टर डॉक में धारा 9.6 "ओवरकॉमिट और ओओएम" का कहना है कि @dunxd उल्लेख विशेष रूप से ओवरकमिटी को अनुमति देने के खतरों पर ग्राफिक है। हालांकि, 80मेरे लिए भी दिलचस्प लग रहा था, इसलिए मैंने कुछ परीक्षण किए।

मैंने पाया कि overcommit_ratioसभी प्रक्रियाओं के लिए उपलब्ध कुल रैम को प्रभावित करता है। रूट प्रक्रियाओं को सामान्य उपयोगकर्ता प्रक्रियाओं से भिन्न नहीं माना जाता है।

अनुपात को 100या उससे कम करने के लिए क्लासिक शब्दार्थ प्रदान करना चाहिए जहां से वापसी मान malloc/sbrkविश्वसनीय हैं। इसे अनुपात से कम सेट करना 100गैर-प्रक्रिया गतिविधियों जैसे कैशिंग और आगे के लिए अधिक रैम आरक्षित करने का एक तरीका हो सकता है।

इसलिए, मेरे कंप्यूटर पर 24 जीएबी रैम के साथ, स्वैप अक्षम के साथ, 9 जीएबी उपयोग में, topदिखाने के साथ

Mem:  24683652k total,  9207532k used, 15476120k free,    19668k buffers
Swap:        0k total,        0k used,        0k free,   241804k cached

यहाँ कुछ overcommit_ratioसेटिंग्स हैं और कितना RAM मेरा राम-उपभोक्ता कार्यक्रम हड़प सकता है (प्रत्येक पृष्ठ को छूना) - प्रत्येक मामले में कार्यक्रम एक बार mallocविफल होने पर सफाई से बाहर निकल जाता है ।

 50    ~680 MiB
 60   ~2900 MiB
 70   ~5200 MiB
100  ~12000 MiB

रूट उपयोगकर्ता के रूप में कुछ के साथ एक बार में कई चल रहे हैं, कुल राशि का एक साथ उपभोग नहीं किया। यह दिलचस्प है कि यह पिछले 3+ GiB या तो उपभोग करने में असमर्थ था; freeबहुत यहाँ क्या दिखाया गया है नीचे ड्रॉप नहीं किया:

Mem:  24683652k total, 20968212k used,  3715440k free,    20828k buffers

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

काल्पनिक रैम के अधिकांश शुरुआती कार्यान्वयन मैंने बहुत ही विशिष्ट मामले को संभालने के लिए किए थे, जहां एक बड़ी प्रक्रिया - उपलब्ध स्मृति का 51% + कहती है - कुछ समर्थन कार्यक्रम के fork()क्रम में आवश्यक exec(), आमतौर पर एक बहुत, बहुत छोटा। कॉपी-ऑन-राइट सेमेटिक्स के साथ ओएस की अनुमति होगी fork(), लेकिन अगर यह साबित हो जाए कि कांटे की प्रक्रिया ने वास्तव में बहुत सारे मेमोरी पेजों को संशोधित करने की कोशिश की है (जिनमें से प्रत्येक को फिर से प्रारंभिक प्रक्रिया से स्वतंत्र एक नए पेज के रूप में इंस्टेंट करना होगा) यह अंत में मार डाला जाएगा। अधिक मेमोरी आवंटित करने पर अभिभावक प्रक्रिया केवल खतरे में थी, और कुछ अन्य प्रक्रिया के मरने के लिए थोड़ा इंतजार करके, और फिर जारी रखने के लिए कुछ मामलों में, बाहर चल रहा है। बच्चे की प्रक्रिया आमतौर पर केवल (आमतौर पर छोटे) कार्यक्रम के माध्यम से खुद को प्रतिस्थापित करती हैexec() और फिर अनंतिम से मुक्त था।

लिनक्स की ओवरकमिट अवधारणा एक चरम दृष्टिकोण है जो दोनों fork()को होने देता है और साथ ही एकल प्रक्रियाओं को व्यापक रूप से समग्र करने की अनुमति देता है। OOM-हत्यारा-कारण होने वाली मौतों एसिंक्रोनस हो भी प्रोग्राम हैं जो करने के लिए करते हैं संभाल स्मृति आवंटन जिम्मेदारी से। मैं व्यक्तिगत रूप से सिस्टम-वाइड ओवरकमिट से सामान्य रूप से नफरत करता हूं और विशेष रूप से ऊम-किलर - यह एक शैतान को बढ़ावा देता है, जो स्मृति प्रबंधन के लिए दृष्टिकोण की देखभाल करता है जो पुस्तकालयों को संक्रमित करता है और उनके माध्यम से हर ऐप जो उनका उपयोग करता है।

मैं 100 के अनुपात को सेट करने का सुझाव दूंगा, और एक स्वैप विभाजन होने के साथ-साथ आम तौर पर केवल बड़ी प्रक्रियाओं द्वारा उपयोग किया जा रहा समाप्त होगा - जो अक्सर केवल स्वयं के हिस्से के एक छोटे से हिस्से का उपयोग कर रहे हैं जो स्वैप में भर जाता है, और इस प्रकार। OOM किलर मिसफिट्योर से प्रक्रियाओं के विशाल बहुमत की रक्षा करें। यह आपके वेबसर्वर को बेतरतीब मौत से सुरक्षित रखना चाहिए, और अगर यह mallocजिम्मेदारी से संभालने के लिए लिखा गया था , यहां तक ​​कि खुद को मारने से भी सुरक्षित है (लेकिन बाद में दांव न लगाएं)।

इसका मतलब है कि मैं इसमें प्रयोग कर रहा हूं /etc/sysctl.d/10-no-overcommit.conf

vm.overcommit_memory = 2
vm.overcommit_ratio = 100

और क्या आप 2 को vm.overcommit_memory रखने की सलाह देंगे?
Ut xD

1
अच्छा नोट - कि वास्तव में मैं क्या उपयोग कर रहा हूं; मुझे लगता है कि मैंने इसे अपने उत्तर में छोड़ दिया क्योंकि यह पहले से ही सवाल में है
एलेक्स नॉर्थ-कीस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.