SSD Nodes Learn Hosting plans →
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-31

systemd తో process memory, CPU పరిమితులు ఎలా పెట్టాలి

MemoryHigh, MemoryMax, CPUQuota, TasksMax అమర్చినా VPS ఎందుకు నిలిచిపోతుందో తెలుసుకోండి. cgroup v2 limits, OOM kill తర్వాత చదవాల్సిన log వివరాలు ఇక్కడ ఉన్నాయి.

systemd drop-in తో process memory మరియు CPU పరిమితులను అమలు చేయండి

Process ను నడిపించే unit కు కొన్ని పంక్తులు జోడించడం ద్వారా Linux VPS లో దాని memory మరియు CPU వినియోగాన్ని పరిమితం చేయవచ్చు. MemoryMax= memory కి గరిష్ఠ పరిమితి. CPUQuota= processor time కు గరిష్ఠ పరిమితి. ఈ రెండింటినీ cgroup v2 (control groups, version 2) అమలు చేస్తుంది. ప్రతి service వినియోగాన్ని లెక్కించడానికి systemd ఇప్పటికే ఉపయోగించే kernel feature ఇదే.

sudo systemctl edit myapp.service

ఇది comments లో సూచనలు ఉన్న drop-in file ను తెరుస్తుంది. ఆ సూచనల పైన ఈ కింది పంక్తులను జోడించండి:

[Service]
MemoryHigh=512M
MemoryMax=768M
MemorySwapMax=0
CPUQuota=80%
TasksMax=128
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl show myapp.service -p MemoryHigh -p MemoryMax -p CPUQuotaPerSecUSec -p TasksMax

systemctl show మీ సంఖ్యలను kernel ఉపయోగించే స్వంత units లోనే మళ్లీ చూపాలి: MemoryMax=805306368 మరియు CPUQuotaPerSecUSec=800ms. అది MemoryMax=infinity ను చూపితే drop-in load కాలేదు. File /etc/systemd/system/myapp.service.d/override.conf వద్ద సరిగ్గా ఉందో, అది [Service] header తో ప్రారంభమవుతుందో తనిఖీ చేయండి. ఎందుకంటే దాని పైన section లేకుండా settings line ఉంటే systemd Assignment outside of section. Ignoring. ను log చేసి, ఎలాంటి limits లేకుండానే service ను ప్రారంభిస్తుంది.

ఈ guide లోని మిగతా భాగం ఆ సంఖ్యలను ఎలా ఎంచుకోవాలి, limits set చేసిన తర్వాత కూడా ఏ సమస్యలు కొనసాగవచ్చు అనే విషయాలను వివరిస్తుంది.

రన్‌అవే process తాను మొత్తం memory నింపకపోయినా VPS ను ఎందుకు నిలిపివేస్తుంది

Hard memory cap ను తాకిన process సుమారు ఒక సెకనులో ముగిసి, service మళ్లీ ప్రారంభమవుతుంది. ఇది మంచి పరిస్థితి. చెడు పరిస్థితిలో ఏదీ ముగియదు: box ping కు సమాధానం ఇస్తుంది, SSH connection ను అంగీకరిస్తుంది, కానీ shell prompt ఎప్పటికీ కనిపించదు. Machine సజీవంగానే ఉండి busy గా ఉంటుంది. అయితే ఆ పని ఏదీ ఉపయోగకరంగా ఉండదు.

ఇది ఎలా జరుగుతుందో చూద్దాం. కారణం వెంటనే స్పష్టంగా ఉండదు. Free memory తగ్గినప్పుడు kernel కొత్త memory ఇవ్వడానికి బదులుగా pages ను reclaim చేస్తుంది. Reclaim చేయడానికి తక్కువ ఖర్చయ్యే pages file-backed pages. నడుస్తున్న ప్రతి దాని executable code ను page cache కలిగి ఉంటుంది. అందువల్ల kernel sshd యొక్క text pages ను తొలగిస్తుంది. తరువాత అమలు కావాల్సిన instruction sshd storage నుంచి ఆ bytes ను మళ్లీ చదవాల్సిన page fault అవుతుంది. ప్రతి process అమలు కావడానికి బదులుగా disk కోసం వేచి ఉంటుంది. అదే pages మళ్లీ మళ్లీ బయటకు వెళ్లి తిరిగి వస్తాయి. దీనినే thrashing అంటారు.

Laptop కంటే VPS లో ఈ సమస్యను పెంచే రెండు కారణాలు ఉన్నాయి. Storage తరచుగా network-attached లేదా shared గా ఉంటుంది. అందువల్ల ప్రతి fault కు local NVMe device కంటే ఎక్కువ milliseconds పడతాయి. అలాగే kernel సమయాన్ని కొలవదు; failure ను కొలుస్తుంది. Reclaim ఎంత నెమ్మదిగా జరిగినా కనీసం ఒక page ను తిరిగి ఇస్తున్నంతకాలం kernel పురోగతి జరుగుతోందని భావిస్తుంది. అందువల్ల out of memory (OOM) killer ను ప్రారంభించదు. ఏ process ను kill చేయకముందే box అనేక నిమిషాలు ఆ స్థితిలో ఉండవచ్చు.

ఇది జరుగుతున్నప్పుడు మీరు గమనించవచ్చు. Linux 4.20 మరియు తదుపరి versions లో kernel pressure stall information (PSI) ను అందిస్తుంది:

cat /proc/pressure/memory
cat /proc/pressure/io
some avg10=63.72 avg60=41.02 avg300=12.33 total=13729481
full avg10=48.15 avg60=30.44 avg300=8.90 total=9114233

full line ముఖ్యమైనది. full avg10=48.15 అంటే గత పది seconds లో 48% సమయంలో box లో runnable గా ఉన్న ప్రతి task memory పనుల కోసం వేచి నిలిచిపోయిందని అర్థం. అందువల్ల ఏదీ అమలు కాలేదు. ఆరోగ్యంగా ఉన్న server లో full విలువ దాదాపు zero గా ఉంటుంది. 10 కంటే ఎక్కువైతే మనిషికి server నెమ్మదిగా అనిపిస్తుంది. 40 లేదా అంతకంటే ఎక్కువైతే ప్రజలు frozen అని వివరించే స్థితి ఏర్పడుతుంది.

అందుకే limit ఒక్కటే హామీ కాదు. MemoryHigh= కింద ఉంచిన unit kill కాకుండా throttle అవుతుంది. కాబట్టి అది సజీవంగానే ఉండి నెమ్మదిగా కొనసాగుతుంది. systemd దృష్టిలో అది ఎప్పుడూ failed కాలేదు. అందువల్ల systemd దాన్ని restart చేయదు. Swap కు ఇంకా అనుమతి ఉన్న capped unit reads మరియు writes ను సృష్టిస్తుంది. వాటి ఖర్చు ఆ unit కు charge అయినప్పటికీ, వాటిని ఒకే shared device అందిస్తుంది. దాంతో box లోని ఇతర services అన్నింటికీ /proc/pressure/io పెరగవచ్చు. Limits కొరతకు ఎవరు ఖర్చు చెల్లించాలో మాత్రమే నిర్ణయిస్తాయి. అవి capacity ను సృష్టించలేవు.

మీ VPS లో cgroup v2 నడుస్తోందో తనిఖీ చేయండి

stat -fc %T /sys/fs/cgroup

cgroup2fs అనేది unified hierarchy. దిగువన ఉన్న ప్రతి setting కు ఇదే అవసరం. tmpfs కనిపిస్తే, సిస్టమ్ పాత v1 layout తో boot అయిందని అర్థం. ఆ layout లో MemoryHigh= మరియు MemorySwapMax= ఉండవు. ప్రతి unit కు సంబంధించిన OOM ప్రవర్తన కూడా భిన్నంగా ఉంటుంది. Ubuntu 22.04 మరియు తరువాతి సంస్కరణలు, అలాగే Debian 11 మరియు తరువాతి సంస్కరణలు, default గా v2 ను ఉపయోగిస్తాయి. పాత image లేదా systemd.unified_cgroup_hierarchy=0 తో boot చేసిన kernel మాత్రం v2 ను ఉపయోగించదు.

cgroup v2 systemd లో ప్రతి unit కు memory accounting ను default గా enable చేస్తుంది. అందువల్ల అవసరమైన సంఖ్యలు ఇప్పటికే అందుబాటులో ఉంటాయి:

systemd-cgtop -m

ఇది memory వినియోగం ఆధారంగా cgroups ను క్రమబద్ధీకరించి చూపుతుంది. సర్వర్ ఇంకా స్పందిస్తున్నప్పుడే “ఈ box లో అధిక వనరులను ఏది వినియోగిస్తోంది?” అనే ప్రశ్నకు సమాధానం తెలుసుకోవడానికి ఇది వేగవంతమైన మార్గం. సర్వర్ కొత్తదైతే, కొత్త VPS లో మొదటి పది నిమిషాల్లో చేయాల్సిన account మరియు firewall పని దీనికంటే ముందు చేయాలి.

MemoryHigh throttles. MemoryMax kills.

ఈ రెండు memory settings మధ్య తేడా వైఫల్యం ఎలా కనిపిస్తుందో నిర్ణయిస్తుంది.

  • MemoryHigh= soft cap. దీనిని మించినప్పుడు kernel ఆ cgroup నుంచి memoryని aggressively reclaim చేస్తుంది మరియు దాని allocations ను ఉద్దేశపూర్వకంగా నెమ్మదిస్తుంది. Usage ఈ పరిమితిని దాటవచ్చు. ఏ process కూడా kill కాదు.
  • MemoryMax= hard cap. దీని పరిధిలో allocation ను అందించలేకపోతే, OOM killer ఆ cgroup లోపలే అమలవుతుంది మరియు ఆ unit కు చెందిన process లలో ఒకదాన్ని kill చేస్తుంది.

మీరు పూర్తిగా విశ్వసించని ఏదైనా సేవపై MemoryMax= సెట్ చేయడానికి ఇదే ప్రధాన కారణం. Cap లేకపోతే memory shortage మొత్తం machine సమస్యగా మారుతుంది. Global OOM killer తన victim ను oom_score ఆధారంగా ఎంచుకుంటుంది. సాధారణంగా దీనర్థం ఎక్కువ memory ఉపయోగిస్తున్న process. ఆ process సాధారణంగా memory leak చేసిన script కాదు, మీ database. Cap ఉంటే, kill దానికి కారణమైన unit లోపలే జరుగుతుంది.

రెండింటినీ సెట్ చేయండి. MemoryHigh= ను MemoryMax= కంటే సుమారు 20 నుంచి 30 శాతం తక్కువగా ఉంచండి. ఈ మధ్యనున్న తేడా warning zone గా పనిచేస్తుంది. నెమ్మదిగా జరిగే leak High ను దాటి, service నెమ్మదిగా మారినట్లు కనిపిస్తుంది. ఆకస్మిక spike మాత్రం Max ను నేరుగా దాటి service ను ఆపేస్తుంది.

Percentage values installed physical memory ఆధారంగా లెక్కించబడతాయి. అందువల్ల 4 GB plan లో MemoryMax=25% అంటే 1 GB. మీరు plan ను resize చేసిన తర్వాత కూడా ఇది machine memoryలో నాలుగో వంతుగానే ఉంటుంది. MemorySwapMax=0 ఆ unit ను swap కు పూర్తిగా దూరంగా ఉంచుతుంది. దీనివల్ల ఎక్కువసేపు కొనసాగే నెమ్మదైన పరిస్థితి బదులుగా త్వరగా మరియు స్పష్టంగా కనిపించే kill జరుగుతుంది.

కొన్ని services వాటి memory అవసరాన్ని ముందుగానే నిర్ణయించుకునే అవకాశం ఇస్తాయి. వాటిని కొలవాల్సిన అవసరం ఉండదు. Ollama unit మీరు ఇచ్చిన context window ఆధారంగా తన KV cache పరిమాణాన్ని నిర్ణయిస్తుంది. అందువల్ల దానికి ceiling ఎంచుకునే ముందు num_ctx పెంచితే RAM పై పడే ప్రభావం ఏమిటో తెలుసుకోండి.

Cap పక్కనే restart policy కూడా ఉండాలి. లేకపోతే kill జరిగిన తర్వాత service stopped స్థితిలోనే ఉంటుంది.

[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Restart=on-failure
RestartSec=5s

StartLimit* ను [Unit] లో ఉంచాలి. Restart= ను [Service] లో ఉంచాలి. వీటిలో ఏదైనా తప్పు section లో ఉంచితే systemd దాన్ని పట్టించుకోదు. ఐదు నిమిషాల్లో ఐదు restarts జరిగితే అది తాత్కాలిక సమస్య కాదు, leak. అందుకే ఆ తర్వాత systemd ప్రయత్నాలను ఆపి unit ను failed స్థితిలో ఉంచుతుంది. తరువాత పరిశీలించాల్సిన స్థితి ఇదే. సమస్యను దాచిపెట్టే crash loop కంటే ఇది మంచిది.

CPUని CPUQuotaతో పరిమితం చేయండి లేదా CPUWeightతో భాగస్వామ్యం చేయండి

CPUQuota= ఒక CPUపై అందుబాటులో ఉన్న సమయానికి శాతాన్ని కేటాయిస్తుంది. CPUQuota=50% ఒక coreలో సగానికి సమానం. CPUQuota=200% రెండు coreలకు సమానం; unit అవసరమైనన్ని threads మధ్య దాన్ని పంపిణీ చేయవచ్చు. 2 vCPU planలో CPUQuota=200% మొత్తం machineకు సమానం.

చాలా servicesకు CPUWeight= మెరుగైన default. ఇది 1 నుంచి 10000 వరకు ఉండే సాపేక్ష భాగస్వామ్యం; kernel default 100. ఏదైనా ఇతర workloadతో పోటీ ఉన్నప్పుడు మాత్రమే దీని ప్రభావం కనిపిస్తుంది: loadలో ఉన్నప్పుడు CPUWeight=20 వద్ద నడిచే backup job, 100 వద్ద నడిచే web serverకు ప్రాధాన్యం ఇస్తుంది. machine idleగా ఉన్నప్పుడు backup job మొత్తం machine సామర్థ్యాన్ని ఉపయోగించగలదు. Hard quota అయితే ఆ idle capacityను ఉపయోగించకుండా వదిలేస్తుంది.

CPU limit మీకు నిజంగా ఏమి ఇస్తుందో వాస్తవికంగా అంచనా వేయండి. CPU-bound process సాధారణంగా Linuxను స్తంభింపజేయదు, ఎందుకంటే scheduler అందరికీ సమయం కేటాయిస్తూ ఉంటుంది. machineను నిలిపివేసేది సాధారణంగా memory. ఊహించదగిన గరిష్ఠ పరిమితి కావాలనుకున్నప్పుడు CPUQuota= ఉపయోగించండి. ఉదాహరణకు, ఒక గంటపాటు పూర్తి వేగంతో నడిచే build లేదా agentకు ఇది ఉపయోగపడుతుంది. ఇలాంటి workloadకు సరైన పరిమాణాన్ని నిర్ణయించడం వేరే అంశం; దీనిని coding agent VPSకు అవసరమైన RAM మరియు CPU పరిమాణం ఎంతలో వివరించాం.

మీ processes ఏవీ ఎక్కువగా పని చేయకపోయినా CPU busyగా కనిపిస్తే, కారణం hypervisorకు అవతలి వైపున ఉండవచ్చు. దీనిని noisy neighbour వల్ల కలిగే CPU steal time అంటారు. మీరు సెట్ చేసిన ఏ quota కూడా దీనిని మార్చదు.

TasksMax fork loop ను ఆపుతుంది

TasksMax= అనేది ఒక unit కలిగి ఉండగల processes మరియు threads సంఖ్య. Threads కూడా లెక్కలోకి వస్తాయి. అందువల్ల process list సూచించే సంఖ్యకన్నా Java లేదా Go సేవకు ఎక్కువ పరిమితి అవసరం. Loop లో fork చేసే script నుంచి రక్షణకు ఇది తక్కువ ఖర్చుతో కూడిన మార్గం. ఎందుకంటే system లో process IDs అయిపోకముందే, ఆ unit లోనే fork విఫలమవుతుంది.

TasksMax=128

ఒక unit ఈ పరిమితిని చేరుకున్నప్పుడు, kernel cgroup పేరును పేర్కొంటూ ఒక log line రాస్తుంది:

cgroup: fork rejected by pids controller in /system.slice/myapp.service

సాధారణంగా ప్రోగ్రామ్ స్వయంగా fork: retry: Resource temporarily unavailable ను నివేదిస్తుంది. manager default గా ఏ విలువను వర్తింపజేస్తుందో systemctl show -p DefaultTasksMax తో పరిశీలించండి.

systemd-run తో ఒకసారి మాత్రమే నడిచే job పరిమితం చేయడం

ఇవన్నీ ఉపయోగించడానికి unit file అవసరం లేదు. systemd-run ఒకే command చుట్టూ తాత్కాలిక unit ను రూపొందిస్తుంది.

sudo systemd-run --scope -p MemoryMax=1G -p MemorySwapMax=0 -p CPUQuota=50% -p TasksMax=64 ./import-data.sh

--scope ముందుగా Running scope as unit: run-r7c1a....scope ను ముద్రించి, మీ terminal లో command ను నడుపుతుంది. Output మీ screenపైనే ఉంటుంది. Command ముగిసినప్పుడు limits తొలగిపోతాయి. systemd.resource-control లోని ఏ property అయినా -p తర్వాత పనిచేస్తుంది.

దీర్ఘకాలం నడిచే job కోసం --scope ను తొలగించి, దానికి ఒక పేరు ఇవ్వండి. అప్పుడు అది backgroundలో transient serviceగా నడుస్తుంది. Logs journalలోకి వెళ్తాయి:

sudo systemd-run --unit=nightly-import -p MemoryMax=1G -p CPUWeight=20 ./import-data.sh
journalctl -u nightly-import -f

మీరు root కాకపోయినా ఇదే options ను --user తో ఉపయోగించవచ్చు. అయితే మీ user managerకు delegate చేసిన controllers మాత్రమే ఉంటాయి. అందువల్ల ఏదైనా property అక్కడ తిరస్కరించబడవచ్చు. అలా జరిగితే sudo తో అమలు చేయండి. ఒక jobకు శాశ్వత స్థానం అవసరమైనప్పుడు, ఈ settings మార్పు లేకుండా నిజమైన unitలోకి తరలించవచ్చు: systemd service మరియు timerగా scriptను నడపడం.

Swap ప్రశ్నకు నిజాయితీగా సమాధానం

Swap వైఫల్యాన్ని నివారించదు. అది వైఫల్యం సంభవించే విధానాన్ని మాత్రమే మారుస్తుంది.

Swap లేకపోతే memory leak పరిమితిని చేరుతుంది. కొన్ని సెకన్లలో ఏదో ఒక process ఆగిపోతుంది. Outage స్పష్టంగా, స్వల్పంగా ఉంటుంది. తరువాత journal లో దాన్ని సులభంగా అర్థం చేసుకోవచ్చు. Swap ఉంటే kernel ఉపయోగంలో లేని anonymous pages ను disk కు రాస్తుంది. దీనివల్ల కొంత సమయం లభిస్తుంది. Process కొంత స్థాయిలో స్థిరపడబోతే swap మిమ్మల్ని కాపాడుతుంది. అది అదుపు తప్పిన process అయితే, swap ఐదు సెకన్ల outage ను ఇరవై నిమిషాల stall గా మారుస్తుంది. ఈ stall మరింత చెడ్డది. ఆగిపోయిన process ఉన్నా shell పనిచేస్తుంది. కానీ thrashing అవుతున్న system లో shell కూడా సరిగా పనిచేయదు.

swapon --show
free -h

చిన్న VPSలో ఉపయోగకరమైన మధ్యస్థ విధానం ఇది: ఒకసారి allocate చేసి తరువాత మళ్లీ ఉపయోగించని pages కోసం పరిమిత పరిమాణంలో swap file ఉంచండి. మీరు ఆపివేయడానికి సిద్ధంగా ఉన్న units పై MemorySwapMax=0 సెట్ చేయండి. ముఖ్యమైన services కు swap అందుబాటులో ఉంచండి. అనూహ్యంగా ప్రవర్తించే services పరిమితిని త్వరగా చేరి restart అవుతాయి.

vm.swappiness విలువను తగ్గించడం బలహీనమైన నియంత్రణ మాత్రమే. ఎందుకో తెలుసుకోవడం ముఖ్యం. ఇది page cache ను తొలగించడం మరియు anonymous pages ను swap చేయడం మధ్య సమతుల్యతను మాత్రమే మారుస్తుంది. రెండింటికీ తరువాత disk read అవసరం అవుతుంది. ఏ pages thrash అవుతాయో ఇది మారుస్తుంది. కానీ system thrash అవుతుందా లేదా అన్నది మార్చదు.

ఆగిపోవడానికి ముందే early OOM daemon ప్రక్రియను నిలిపివేస్తుంది

reclaim పూర్తిగా విఫలమయ్యే వరకు kernel వేచి ఉంటుంది. చిన్న VPSలో ఆ వేచి ఉండే సమయమే మీరు machine ను కోల్పోయే ఖచ్చితమైన వ్యవధి. memory ను స్వయంగా పర్యవేక్షించి, ముందుగానే ప్రక్రియలను నిలిపివేసే రెండు userspace daemons ఈ వ్యవధిని తగ్గిస్తాయి.

earlyoom అందుబాటులో ఉన్న memory మరియు free swap ను పర్యవేక్షిస్తుంది. వీటిలో ఏదైనా threshold కంటే దిగువకు పడితే, అత్యధిక score ఉన్న process ను నిలిపివేస్తుంది.

sudo apt install earlyoom
systemctl status earlyoom

Debian మరియు Ubuntu package install సమయంలో service ను ప్రారంభిస్తుంది. దీని options /etc/default/earlyoom లో ఉంటాయి:

EARLYOOM_ARGS="-m 5,2 -s 5,2 --avoid '^(sshd|systemd)$' --prefer '^(node|python3)$'"

-m PERCENT available memory minimum ను, -s PERCENT free swap minimum ను నిర్దేశిస్తుంది. రెండింటి default విలువ 10 percent. ప్రతి pair లోని రెండవ సంఖ్య SIGKILL threshold. మొదటి విలువ కంటే దిగువకు వెళ్లగానే earlyoom SIGTERM పంపుతుంది. రెండవ విలువ కంటే దిగువకు వెళ్లినప్పుడు SIGKILL పంపుతుంది. రెండవ విలువ default గా మొదటి విలువలో సగం ఉంటుంది. మార్పును sudo systemctl restart earlyoom తో అమలు చేయండి. ఏ process ను నిలిపివేసిందో, ఆ process ఎంత memory ఉపయోగించిందో చూడటానికి journalctl -u earlyoom చదవండి.

systemd-oomd మరో option. దీని manual page దీనిని "kernel space లో OOM సంభవించే ముందు cgroups-v2 మరియు pressure stall information (PSI) ఉపయోగించి పర్యవేక్షించి, సరిదిద్దే చర్యలు తీసుకునే system service"గా వివరిస్తుంది. ఇది single processes బదులుగా మొత్తం cgroups పై పనిచేస్తుంది. అందువల్ల stray child ను కాకుండా ఒక unit ను నిలిపివేస్తుంది. Units ManagedOOMMemoryPressure=kill లేదా ManagedOOMSwap=kill తో opt in అవుతాయి. Thresholds /etc/systemd/oomd.conf లో ఉంటాయి.

systemctl status systemd-oomd
oomctl

ప్రస్తుతం ఏవి పర్యవేక్షణలో ఉన్నాయో oomctl చూపిస్తుంది. Server image లో ఇది తరచుగా ఏమీ చూపించదు, ఎందుకంటే setting ప్రతి unit కు opt-in విధానంలో ఉంటుంది. ఒక daemon ను ఎంచుకుని దానితోనే ఆగండి. రెండింటినీ నడిపితే victim ను ఎంచుకోవడానికి రెండు daemons పోటీ పడతాయి. అప్పుడు kill కు కారణాన్ని తరువాత పునర్నిర్మించడం కష్టమవుతుంది.

ఏ unit బాధ్యత వహించింది?

ముందుగా kernel ను పరిశీలించండి. అది అమలు చేసిన ప్రతి kill ను నమోదు చేస్తుంది.

journalctl -k --grep "Killed process" --since "2 hours ago"

Global OOM killer చేసిన kill సాధారణంగా ఇలా కనిపిస్తుంది:

Out of memory: Killed process 4127 (node) total-vm:2731084kB, anon-rss:1874232kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:4212kB oom_score_adj:0

anon-rss అనేది ఆ process ముగిసే సమయంలో RAMలో ఉన్న memory. ఇక్కడ అది సుమారు 1.8 GB. Brackets లోని name ను జాగ్రత్తగా పరిగణించండి. Kernel ఎంచుకున్న victim అదే. అయితే kernel ఎంచుకునేది అతిపెద్ద process ను మాత్రమే; memory కొరతకు కారణమైన process అదే అయి ఉండాల్సిన అవసరం లేదు.

cgroup limit కారణంగా జరిగిన kill కు prefix వేరుగా ఉంటుంది. దాని పైన ముద్రించిన report, తన ceiling ను తాకిన cgroup పేరును చూపిస్తుంది:

Memory cgroup out of memory: Killed process 8811 (python3) total-vm:1044320kB, anon-rss:769112kB, file-rss:0kB, shmem-rss:0kB, UID:998 pgtables:1720kB oom_score_adj:0

ఆ prefix తోనే diagnosis లో ఎక్కువ భాగం తెలుస్తుంది. Memory cgroup out of memory అంటే మీరు ఇచ్చిన MemoryMax= ను ఒక unit తాకింది, కానీ మిగిలిన systemలో సమస్య లేదు. సాధారణ Out of memory అంటే మొత్తం machineలో memory అయిపోయింది. అంటే మీ caps లేవు లేదా కలిపి చూస్తే చాలా ఎక్కువగా ఉన్నాయి.

తరువాత systemd ఏమి గమనించిందో అడగండి:

systemctl status myapp.service
journalctl -u myapp.service -n 50
myapp.service: A process of this unit has been killed by the OOM killer.
myapp.service: Main process exited, code=killed, status=9/KILL
myapp.service: Failed with result 'oom-kill'.

systemctl status అదే విషయాన్ని ఒక lineలో చెబుతుంది, Active: failed (Result: oom-kill) గా.

cgroup counters మూడవ source. Throttling ను నమోదు చేసేది ఇదొక్కటే. Throttling వల్ల ఎప్పుడూ log line ఉత్పత్తి కాదు:

cat /sys/fs/cgroup/system.slice/myapp.service/memory.events
cat /sys/fs/cgroup/system.slice/myapp.service/memory.peak
low 0
high 4213
max 118
oom 12
oom_kill 12

high unit ను MemoryHigh= పరిమితికి మించి నడిపి throttled చేసిన సార్లు ఎన్ని ఉన్నాయో లెక్కిస్తుంది. max hard cap ను తాకిన సార్లు ఎన్ని ఉన్నాయో లెక్కిస్తుంది. oom_kill వాస్తవంగా kill అయిన processes సంఖ్యను లెక్కిస్తుంది. oom_kill 0 తో పాటు పెద్ద high ఉంటే, అది ముందుగా చెప్పిన silent case. Service నడుస్తూనే ఉంటుంది, చాలా నెమ్మదిగా మారుతుంది, కానీ ఎవరికీ failure తెలియజేయదు. memory.peak (Linux 5.19 మరియు తరువాతి versions) cgroup చేరుకున్న అత్యధిక usage ను ఉంచుతుంది. MemoryMax= పరిమాణాన్ని నిర్ణయించేటప్పుడు ఉపయోగించాల్సిన సంఖ్య ఇదే. Unit restart అయినప్పుడు రెండు files reset అవుతాయి. ఎందుకంటే systemd cgroup ను మళ్లీ సృష్టిస్తుంది.

ఈ మొత్తం వ్యవస్థకు ఒక prerequisite అవసరం. /var/log/journal లేకపోతే journal RAMలోనే ఉంటుంది. Box ను recover చేయడానికి అవసరమైన reboot తర్వాత ప్రతి line పోతుంది.

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots

journalctl --list-boots ప్రస్తుత boot కంటే ఎక్కువ history చూపిస్తే, ఇప్పుడు history నిల్వ ఉంటుంది. అందువల్ల చనిపోయిన boot కు చెందిన kernel messages ను journalctl -k -b -1 చూపించగలదు.

చిన్న VPS కోసం ప్రారంభ పరిమితులు

2 GB plan లో kernel మరియు page cache కోసం 300 నుంచి 400 MB వరకు కేటాయించండి. అన్ని limits కలిపి పూర్తి 2 GBకు చేరేలా చేయవద్దు. ప్రతి unit ఒకేసారి గరిష్ఠ memoryని ఉపయోగించవచ్చు. ముఖ్యమైన service కు ఎక్కువ భాగాన్ని ఇవ్వండి. దాని చుట్టూ ఉన్న ప్రయోగాత్మక services అన్నింటికీ పరిమితులు విధించండి.

[Service]
MemoryHigh=256M
MemoryMax=384M
MemorySwapMax=0
CPUWeight=20
TasksMax=64
Restart=on-failure
RestartSec=5s

సిస్టమ్‌లోకి ప్రవేశించే మార్గాన్ని కొనసాగించడానికి మరో setting ఉపయోగపడుతుంది. OOMScoreAdjust=-500 ను ssh.service కోసం drop-in లో అమలు చేస్తే, global OOM killer మీ SSH daemon ను victim గా ఎంచుకునే అవకాశం గణనీయంగా తగ్గుతుంది. దీనివల్ల box ను సరిచేయవచ్చు; control panel నుంచి reboot చేయాల్సిన పరిస్థితి రాదు. ఇది victim ను ఎంచుకునే kernel నిర్ణయాన్ని మాత్రమే మారుస్తుంది. stall వ్యవధిని తగ్గించదు.

Containers తమ స్వంత cgroups లో నడుస్తాయి. ఈ cgroups ను మీ unit files కాకుండా container runtime సృష్టిస్తుంది. అందువల్ల docker.service పై విధించిన limit ఒక container కు limit గా మారదు. ప్రతి container కు వర్తించే MemoryMax= మరియు CPUQuota= సమానమైన settings గురించి Docker Compose లో memory మరియు CPU limits అమర్చడం లో వివరించబడింది.

FAQ

నా VPS runaway process ను terminate చేయకుండా ఎందుకు freeze అయింది?

Reclaim ద్వారా pages తిరిగి అందుబాటులోకి వస్తున్నాయా లేదా అన్నదానిపై kernel progress ను అంచనా వేస్తుంది. దీనికి ఎంత సమయం పడుతుందో అది పరిగణనలోకి తీసుకోదు. Memory తక్కువగా ఉన్నప్పుడు, running programs యొక్క executable pages సహా page cache ను అది evict చేస్తుంది. తరువాతి instruction అవసరమైనప్పుడు ఆ pages ను మళ్లీ చదువుతుంది. అందరూ storage పై వేచి ఉంటారు. Allocation సాంకేతికంగా విఫలం కాలేదు. అందువల్ల OOM killer ఎప్పుడూ ప్రారంభం కాదు. సమస్య జరుగుతున్నప్పుడు /proc/pressure/memory ను పరిశీలించండి. full avg10 విలువ 40 కంటే ఎక్కువగా ఉంటే, గత పది seconds లో దాదాపు ఏ task కూడా run కాలేదని అర్థం. earlyoom వంటి userspace daemon, machine ఆ స్థితికి చేరకముందే process ను terminate చేస్తుంది.

MemoryHigh మరియు MemoryMax మధ్య తేడా ఏమిటి?

MemoryHigh= అనేది throttling చేసే soft cap. Kernel ఆ unit నుంచి pages ను బలవంతంగా reclaim చేస్తుంది మరియు దాని allocations ను నెమ్మదిస్తుంది. అయితే usage ఆ సంఖ్యను మించవచ్చు. ఏ process కూడా terminate చేయబడదు. MemoryMax= అనేది hard cap. దాని పరిమితిలో allocation ను అందించలేకపోతే, ఆ unit స్వంత cgroup లో OOM killer ను ప్రారంభిస్తుంది. అందువల్ల సమస్యకు కారణమైన process terminate అవుతుంది. Machine లో అత్యధిక memory ఉపయోగిస్తున్న process terminate కాదు. MemoryHigh= ను MemoryMax= కంటే తక్కువగా సెట్ చేయండి. ఈ రెండింటి మధ్య ఉన్న వ్యత్యాసాన్ని warning zone గా పరిగణించండి.

OOM killer ఏ service ను ప్రభావితం చేసిందో ఎలా కనుగొనాలి?

journalctl -k --grep "Killed process" --since "2 hours ago" ను run చేయండి. Memory cgroup out of memory తో ప్రారంభమయ్యే line కనిపిస్తే, ఒక unit తన స్వంత MemoryMax= పరిమితిని తాకిందని అర్థం. సాధారణ Out of memory కనిపిస్తే, మొత్తం machine లో memory అయిపోయిందని అర్థం. తరువాత journalctl -u <unit> -n 50 ను run చేసి Failed with result 'oom-kill' కోసం చూడండి. మీ server లో /var/log/journal లేకపోతే, journal RAM లోనే ఉంచబడిందని అర్థం. Reboot సమయంలో ఆ ఆధారం పోయింది. అందువల్ల తదుపరి incident కు ముందు ఆ directory ను సృష్టించండి.

చిన్న VPS కు swap జోడించాలా?

ఒకసారి allocate చేసి తరువాత మళ్లీ ఉపయోగించని cold pages కోసం చిన్న swap file సహాయపడుతుంది. Runaway process కు ఇది సహాయపడదు. ఇది process termination ను ఆలస్యం చేస్తుంది. దాంతో చిన్న outage బదులుగా, login చేసి పరిష్కరించలేని దీర్ఘమైన stall ఏర్పడుతుంది. Swap ను పరిమితంగా ఉంచండి. మీరు terminate కావడానికి అనుమతించే units పై MemorySwapMax=0 ను సెట్ చేయండి. అప్పుడు అవి తమ ceiling ను చేరుకుని త్వరగా restart అవుతాయి. ముఖ్యమైన services మాత్రం తమ swap ను కొనసాగిస్తాయి.

Unit file రాయకుండా ఒక command కు పరిమితి విధించవచ్చా?

అవును. sudo systemd-run --scope -p MemoryMax=1G -p CPUQuota=50% ./script.sh మీ terminal లో ఆ command ను transient scope లో, పేర్కొన్న limits తో run చేస్తుంది. Command exit అయినప్పుడు ఆ limits తొలగిపోతాయి. systemd.resource-control లోని ప్రతి property -p తరువాత అందుబాటులో ఉంటుంది. అందువల్ల MemorySwapMax=, TasksMax= మరియు CPUWeight= కూడా అక్కడ పనిచేస్తాయి. --scope ను తీసివేసి, --unit=name ను జోడిస్తే job background లో run అవుతుంది. దాని output journal లో నమోదు అవుతుంది.