एक प्रक्रिया और उसके बच्चों के कुल संसाधनों (स्मृति) को कैसे सीमित करें


16

किसी एकल प्रक्रिया के संसाधनों को सीमित करने के बारे में बहुत सारे प्रश्न और उत्तर हैं, जैसे RLIMIT_AS का उपयोग एक प्रक्रिया द्वारा आवंटित अधिकतम मेमोरी को बाधित करने के लिए किया जा सकता है जिसे पसंद में VIRT के रूप में देखा जा सकता है top। विषय पर अधिक यहाँ उदाहरण है कि क्या यूनिक्स में उपयोग की जाने वाली मेमोरी की मात्रा को सीमित करने का एक तरीका है?

setrlimit(2) प्रलेखन कहता है:

कांटा (2) के माध्यम से बनाई गई एक बाल प्रक्रिया अपने माता-पिता की संसाधन सीमाओं को प्राप्त करती है। संसाधन सीमाओं को निष्पादित (2) के पार संरक्षित किया जाता है।

इसे निम्नलिखित तरीके से समझा जाना चाहिए:

यदि किसी प्रक्रिया में 2GB का RLIMIT_AS है, तो यह 2GB से अधिक मेमोरी आवंटित नहीं कर सकता है। जब यह एक बच्चे को जन्म देता है, तो 2GB का पता स्थान सीमा बच्चे को दिया जाएगा, लेकिन गिनती 0. से शुरू होती है। 2 प्रक्रियाएं एक साथ 4GB तक मेमोरी ले सकती हैं।

लेकिन प्रक्रियाओं के एक पूरे पेड़ द्वारा आवंटित स्मृति के योग को बाधित करने के लिए उपयोगी तरीका क्या होगा?



7
मैं देख लेता हूँ cgroups
स्लम

@ एसएलएम धन्यवाद! Cgroups की तरह लगता है कुछ करने की कोशिश है। इस तक का एकमात्र कार्य समाधान (पीएस का उपयोग करके मेमोरी का एक बदसूरत तरीका है और अगर ऊपर की सीमा है तो माता-पिता की प्रक्रिया को मारना) जो काम कर सकता है कंटेनर (lxc या पसंद) के कुछ रूप का उपयोग कर रहा है।
JPE

हाँ - जिन उपकरणों के बारे में मैं जानता हूँ, वे एक समूह, सिर्फ एक प्रक्रिया नहीं करते हैं, लेकिन यह देखते हुए कि कैसे cgroups VM प्रौद्योगिकियों जैसे LXC और Docker के लिए काम करते हैं, मैं यह अपेक्षा करता हूँ कि आप क्या चाहते हैं।
SLM

1
यदि यह लिनक्स पेरेंट पीआईडी ​​को अपने नामस्थान में रख देता है और इसे और इसके सभी बच्चों को इस तरह नियंत्रित करता है। यहाँ उस अवधारणा का परिचयात्मक उत्तर दिया गया है: unix.stackexchange.com/a/124194/52934
mikeserv

जवाबों:


8

मुझे यकीन नहीं है कि यह आपके प्रश्न का उत्तर देता है, लेकिन मुझे यह पर्ल स्क्रिप्ट मिली जो दावा करती है कि आप जो खोज रहे हैं वह ठीक है। स्क्रिप्ट प्रक्रिया और उसके बच्चों के संसाधन उपयोग को जाग्रत करके सीमाओं को लागू करने के लिए अपने स्वयं के सिस्टम को लागू करती है। यह अच्छी तरह से प्रलेखित और समझाया गया है, और हाल ही में अपडेट किया गया है।

जैसा कि स्लम ने अपनी टिप्पणी में कहा, इसके लिए cgroups का भी उपयोग किया जा सकता है। आपको cgroups को प्रबंधित करने के लिए उपयोगिताओं को स्थापित करना पड़ सकता है, यह मानते हुए कि आप लिनक्स पर हैं जिसे आपको देखना चाहिए libcgroups

sudo cgcreate -t $USER:$USER -a $USER:$USER -g memory:myGroup

सुनिश्चित करें कि $USERआपका उपयोगकर्ता है।

तब आपके उपयोगकर्ता के पास cgroup मेमोरी सेटिंग्स तक पहुंच होनी चाहिए /sys/fs/cgroup/memory/myGroup

फिर आप यह करने के लिए सीमा 500 एमबी कह सकते हैं,

echo 500000000 > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes

अब Vim चलाने दें:

cgexec -g memory:myGroup vim

विम प्रक्रिया और उसके सभी बच्चों को अब 500 एमबी रैम का उपयोग करने के लिए सीमित होना चाहिए। हालाँकि , मुझे लगता है कि यह सीमा केवल रैम पर लागू होती है और स्वैप नहीं। एक बार जब प्रक्रिया सीमा तक पहुंच जाएगी तो वे स्वैप करना शुरू कर देंगे। मुझे यकीन नहीं है कि अगर आप इसके आसपास हो सकते हैं, तो मैं cgroups का उपयोग करके स्वैप उपयोग को सीमित करने का एक तरीका नहीं ढूंढ सकता हूं।


प्रस्तावित समाधान प्रक्रियाओं के एक पेड़ के निवासी सेट आकार को सीमित करना संभव बनाता है। व्यवहार RLIMIT_AS से भिन्न प्रतीत होता है: सीमा से अधिक मेमोरी को मॉलोक करना संभव है, हालांकि यह वास्तव में अधिक उपयोग करने के लिए संभव नहीं लगता है।
जेपी

डिफ़ॉल्ट रूप से, cgroup मेमोरी लिमिट केवल (लगभग) भौतिक RAM उपयोग पर लागू होती है। स्वैप अकाउंटिंग को सक्षम करने के लिए एक कर्नेल विकल्प (CONFIG_MEMCG_SWAP) है; देख गिरी डॉक्स जानकारी के लिए।
सोरेन लोर्बोर्ग

1
फेडोरा पर,sudo yum install libcgroup-tools
jozxyqk

2

मैंने एक स्क्रिप्ट बनाई जो ऐसा करती है, जो cgmanager का उपयोग करती है जो उबंटू में प्रयोग किया जाता है। एक फायदा यह है कि इसके लिए रूट एक्सेस की आवश्यकता नहीं होती है। ध्यान दें कि cgroup प्रबंधन थोड़ा डिस्ट्रो विशिष्ट है, इसलिए मुझे नहीं पता कि यह सिस्टम सिस्टम cgroup प्रबंधन का उपयोग करने वाले distros पर काम करता है या नहीं।

#!/bin/sh

set -eu

if [ "$#" -lt 2 ]
then
    echo Usage: `basename $0` "<limit> <command>..."
    exit 1
fi

limit="$1"
shift
cgname="limitmem_$$"
echo "limiting memory to $limit (cgroup $cgname) for command $@"

cgm create memory "$cgname" >/dev/null
cgm setvalue memory "$cgname" memory.limit_in_bytes "$limit" >/dev/null
# try also limiting swap usage, but this fails if the system has no swap
cgm setvalue memory "$cgname" memsw.limit_in_bytes "$limit" >/dev/null 2>&1 || true

# spawn subshell to run in the cgroup
set +e
(
set -e
cgm movepid memory "$cgname" `sh -c 'echo $PPID'` > /dev/null
exec "$@"
)
# grab exit code
exitcode=`echo $?`

set -e

echo -n "peak memory used: "
cgm getvalue memory "$cgname" memory.max_usage_in_bytes | tail -1 | cut -f2 -d\"

cgm remove memory "$cgname" >/dev/null
exit $exitcode

उपयोग: limitmemअपने पथ के रूप में सहेजें और इसे निष्पादन योग्य बनाएं। फिर उदा limitmem 1G command...। यह वास्तव में उपयोग की जाने वाली मेमोरी को सीमित करता है। अगर वह OOM हत्यारे तक पहुँच जाता है तो वह इस प्रक्रिया या उसके एक बच्चे को मार देगा, लेकिन ऐसा कुछ यादृच्छिक नहीं जिसका इस कमान से कोई लेना-देना नहीं है।


लघु cgmमार्गदर्शिका के लिए धन्यवाद , यह उपयोगी था
विटाली इसव

1

/unix//a/536046/4319 :

किसी भी सिस्टम-आधारित डिस्ट्रो पर आप सिस्टम-रन के माध्यम से परोक्ष रूप से cgroups का उपयोग कर सकते हैं। pdftoppm500M RAM तक सीमित करने के आपके मामले के लिए, उदाहरण के लिए :

systemd-run --scope -p MemoryLimit=500M pdftoppm

...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.