SSD Nodes Learn 🎉 VPS kutoka $5.50/mwezi
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-08-13

Jinsi ya kupunguza matumizi ya CPU na RAM kwa systemd

Zuia mchakato usikwamishe VPS yako kwa kutumia MemoryMax na CPUQuota. Jifunze kusanidi cgroup v2, kuepuka kosa la Unit configuration, na kusoma logi za OOM kill kwa usahihi.

Kuwekea mchakato mipaka ya kumbukumbu na CPU kwa kutumia systemd drop-in

Unaweka mipaka ya kumbukumbu na CPU ya mchakato kwenye VPS ya Linux kwa kuongeza mistari michache kwenye unit inayouendesha mchakato huo. MemoryMax= ni kikomo cha juu cha kumbukumbu. CPUQuota= ni kikomo cha muda wa processor. Vyote vinasimamiwa na cgroup v2 (control groups, version 2), kipengele cha kernel ambacho systemd tayari inakitumia kufuatilia kila huduma kwenye seva.

sudo systemctl edit myapp.service

Hiyo inafungua faili ya drop-in yenye maelekezo kwenye maoni. Ongeza mistari hii hapo juu:

[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 lazima irudishe namba zako katika vipimo vya kernel: MemoryMax=805306368 na CPUQuotaPerSecUSec=800ms. Ikiwa inachapisha MemoryMax=infinity, drop-in haikupakiwa. Hakikisha faili imetua kwenye /etc/systemd/system/myapp.service.d/override.conf, na kwamba inaanza na kichwa cha habari cha [Service], kwa sababu mstari wa mipangilio usio na sehemu juu yake huifanya systemd kuandika Assignment outside of section. Ignoring. kwenye logi na kuanzisha huduma bila mipaka yoyote.

Sehemu iliyobaki ya mwongozo huu ni jinsi ya kuchagua namba hizo, na nini kinachoweza kwenda vibaya baada ya kuwekwa.

Kwa nini mchakato unaokimbia bila mpangilio hugandisha VPS hata kama haujajaza kumbukumbu

Mchakato unaofikia kikomo cha kumbukumbu hufa ndani ya sekunde moja na huduma huanza upya. Hiyo ndiyo hali nzuri. Hali mbaya ni ile ambapo hakuna kinachokufa: seva inajibu ping, SSH inakubali muunganisho, lakini prompt ya shell haiji kamwe. Mashine iko hai na ina shughuli nyingi, na hakuna kazi hiyo inayofaa.

Huu hapa ni utaratibu wake, kwa sababu si dhahiri. Kumbukumbu inapopungua, kernel hurejesha kurasa (pages) badala ya kutoa mpya. Kurasa za bei nafuu zaidi kurejeshwa ni zile zinazotegemea faili, na page cache hushikilia msimbo wa executable wa kila kitu kinachoendelea. Kwa hivyo, kernel huondoa kurasa za maandishi za sshd, na maagizo yanayofuata ambayo sshd huendesha ni page fault inayolazimika kusoma baiti hizo kutoka kwenye hifadhi. Kila mchakato huishia kusubiri diski badala ya kuendesha. Kurasa zilezile huondoka na kurudi katika mzunguko, jambo linaloitwa thrashing.

Mambo mawili hufanya hali hii kuwa mbaya zaidi kwenye VPS kuliko kwenye kompyuta ya mkononi. Hifadhi mara nyingi huunganishwa kupitia mtandao au kushirikiwa, kwa hivyo kila fault hugharimu milisekunde nyingi zaidi kuliko kifaa cha ndani cha NVMe. Na kernel haipimi muda, inapima kushindwa: mradi tu urejeshaji unaendelea kutoa ukurasa, hata kwa polepole, kernel huamini kuwa inafanya maendeleo na haitoi amri ya out of memory (OOM) killer. Seva inaweza kukaa katika hali hiyo kwa dakika nyingi kabla ya kitu chochote kuuawa.

Unaweza kutazama jambo hili likitokea. Kernel hutoa taarifa za pressure stall information (PSI) kwenye Linux 4.20 na matoleo mapya zaidi:

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

Mstari wa full ndio unaohusika. full avg10=48.15 inamaanisha kuwa katika sekunde kumi zilizopita, 48% ya muda kila kazi inayoweza kuendeshwa kwenye seva ilikwama ikisubiri kazi ya kumbukumbu, kwa hivyo hakuna kilichoendeshwa. Seva yenye afya husoma karibu na sifuri kwenye full. Zaidi ya 10 huhisiwa kuwa polepole na binadamu, na 40 au zaidi ni hali ambayo watu huielezea kama kuganda.

Hii ndiyo sababu kikomo pekee si ahadi. Kitengo kinachoshikiliwa chini ya MemoryHigh= hupunguzwa kasi badala ya kuuawa, kwa hivyo kinabaki hai na kinabaki polepole, na hakuna kinachokianzisha upya kwa sababu kwa mtazamo wa systemd hakijawahi kushindwa. Kitengo kilichowekewa kikomo ambacho bado kinaruhusiwa kutumia swap huzalisha usomaji na uandishi unaotozwa kwa kitengo hicho lakini unaohudumiwa na kifaa kimoja kinachoshirikiwa, kwa hivyo kinaweza kupandisha /proc/pressure/io kwa kila huduma nyingine kwenye seva. Vikomo huamua nani anayelipia uhaba, na haviwezi kuunda uwezo wa ziada.

Hakikisha VPS yako inatumia cgroup v2

stat -fc %T /sys/fs/cgroup

cgroup2fs ndiyo mfumo wa uongozi uliounganishwa, ambao ndio unaohitajika kwa kila mpangilio hapa chini. tmpfs inamaanisha kuwa seva ilianza kwa kutumia mpangilio wa zamani wa v1, ambapo MemoryHigh= na MemorySwapMax= havipo na tabia ya OOM kwa kila unit ni tofauti. Ubuntu 22.04 na matoleo mapya zaidi, pamoja na Debian 11 na matoleo mapya zaidi, hutumia v2 kwa chaguo-msingi. Image ya zamani, au kernel iliyoanzishwa kwa systemd.unified_cgroup_hierarchy=0, haitumii v2.

Kwenye cgroup v2, systemd huwasha uhasibu wa kumbukumbu (memory accounting) kwa kila unit kwa chaguo-msingi, kwa hivyo namba hizo tayari zipo:

systemd-cgtop -m

Hiyo huorodhesha cgroups zilizopangwa kulingana na matumizi ya kumbukumbu, ambayo ndiyo njia ya haraka zaidi ya kujibu "ni nini kinachotumia rasilimali za seva hii" wakati bado inaweza kujibu. Ikiwa seva ni mpya, kazi ya akaunti na firewall katika dakika kumi za kwanza kwenye VPS mpya inapaswa kufanyika kabla ya hatua hii.

MemoryHigh husababisha throttling. MemoryMax huua mchakato.

Tofauti kati ya mipangilio hii miwili ya kumbukumbu huamua jinsi hitilafu inavyoonekana.

  • MemoryHigh= ni kikomo laini (soft cap). Inapovukwa, kernel hurejesha kumbukumbu kwa nguvu kutoka kwa cgroup hiyo na kupunguza kasi ya ugawaji wa kumbukumbu kwa makusudi. Matumizi yanaweza kuzidi namba hiyo, na hakuna mchakato unaouawa.
  • MemoryMax= ni kikomo kigumu (hard cap). Ugawaji wa kumbukumbu unaposhindikana chini ya kikomo hiki, OOM killer hufanya kazi ndani ya cgroup hiyo na kuua mchakato mmoja wa unit hiyo.

Nusu ya pili ndiyo sababu kuu ya kuweka MemoryMax= kwenye kitu chochote ambacho hukiamini kikamilifu. Bila kikomo, uhaba wa kumbukumbu huwa tatizo la seva nzima, na OOM killer ya mfumo mzima huchagua mwathiriwa kulingana na oom_score, ambayo mara nyingi humaanisha mchakato mkubwa zaidi. Mchakato mkubwa zaidi kwa kawaida ni database yako, si script iliyovuja kumbukumbu. Ukiwa na kikomo, mauaji hutokea ndani ya unit iliyosababisha tatizo.

Weka zote mbili, huku MemoryHigh= ikiwa asilimia 20 hadi 30 chini ya MemoryMax=. Pengo hilo ni eneo la onyo: uvujaji wa polepole huvuka High na kuonekana kama huduma iliyopungua kasi, wakati ongezeko la ghafla hupita moja kwa moja kupitia Max na kufa.

Thamani za asilimia hulinganishwa na kumbukumbu halisi iliyopo (physical memory), kwa hivyo MemoryMax=25% kwenye mpango wa 4 GB ni 1 GB na itabaki kuwa robo ya seva hata ukibadilisha ukubwa wa mpango huo. MemorySwapMax=0 huizuia unit hiyo kutumia swap kabisa, jambo linalobadilisha mchakato wa polepole kuwa mauaji ya haraka na ya wazi.

Kikomo kinahitaji sera ya kuanzisha upya (restart policy) kando yake, vinginevyo mauaji hayo yatakuachia huduma iliyosimama tu.

[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5

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

StartLimit* inapaswa kuwekwa kwenye [Unit] na Restart= kwenye [Service]. Ukiweka mojawapo kwenye sehemu isiyo sahihi, systemd itaipuuza. Kuanzisha upya mara tano ndani ya dakika tano ni ishara ya uvujaji badala ya tatizo la muda mfupi, kwa hivyo baada ya hapo systemd huacha kujaribu na kuiacha unit ikiwa katika hali ya failed, hali ambayo unataka kuikuta baadaye badala ya crash loop inayoficha tatizo.

Punguza matumizi ya CPU kwa CPUQuota, au igawanye kwa CPUWeight

CPUQuota= huchukua asilimia ya muda unaopatikana kwenye CPU moja. CPUQuota=50% ni nusu ya core moja. CPUQuota=200% ni sawa na cores mbili, ambazo kitengo kinaweza kuzisambaza kwenye threads nyingi kadiri kinavyotaka. Kwenye mpango wa 2 vCPU, CPUQuota=200% ni mashine nzima.

CPUWeight= ni chaguo-msingi bora kwa huduma nyingi. Ni sehemu ya uwiano kuanzia 1 hadi 10000, na chaguo-msingi la kernel ni 100. Hufanya kazi tu wakati kuna ushindani: kazi ya backup iliyowekwa kwenye CPUWeight=20 itapisha web server iliyo kwenye 100 wakati wa mzigo mkubwa, na bado itatumia mashine nzima wakati haina kazi. Hard quota hupoteza uwezo huo wa ziada.

Kuwa mkweli kuhusu faida ya kikomo cha CPU. Mchakato unaotumia CPU nyingi mara chache hufungia Linux, kwa sababu scheduler huendelea kutoa muda kwa kila mtu. Kumbukumbu (RAM) ndiyo inayoweza kuangusha seva. Tumia CPUQuota= unapotaka ukomo unaotabirika, kwa mfano kwenye build au agent ambayo ingeweza kufanya kazi kwa kasi ya juu kwa saa nzima. Kupima ukubwa wa mzigo wa aina hiyo ni swali tofauti, linalojadiliwa katika kiasi gani cha RAM na CPU ambacho VPS ya coding agent inahitaji.

Ikiwa CPU inaonekana kuwa na shughuli nyingi wakati hakuna michakato yako inayofanya kazi nyingi, sababu inaweza kuwa upande mwingine wa hypervisor. Hiyo ni CPU steal time kutoka kwa jirani mwenye kelele, na hakuna quota utakayoweka itakayobadilisha hali hiyo.

TasksMax inazuia mzunguko wa fork

TasksMax= ni idadi ya processes na threads ambazo unit inaweza kuwa nazo. Threads huhesabiwa, kwa hivyo huduma ya Java au Go inahitaji nafasi zaidi kuliko orodha ya process inavyoashiria. Hii ndiyo njia rahisi zaidi ya kujilinda dhidi ya script inayofanya fork kwa mzunguko, kwa sababu fork inafeli ndani ya unit badala ya seva kuishiwa na process IDs.

TasksMax=128

Wakati unit inapofikia kikomo hiki, kernel huandika ujumbe kwenye logi ikitaja cgroup husika:

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

Programu yenyewe kwa kawaida huripoti fork: retry: Resource temporarily unavailable. Angalia kile ambacho meneja hutumia kama chaguo-msingi kwa kutumia systemctl show -p DefaultTasksMax.

Kuwekea kikomo kazi ya mara moja kwa kutumia systemd-run

Hauhitaji unit file ili kutumia chochote kati ya hivi. systemd-run hutengeneza unit ya muda mfupi kuzunguka amri moja.

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

--scope huendesha amri hiyo kwenye terminal yako, baada ya kuchapisha Running scope as unit: run-r7c1a....scope. Matokeo hubaki kwenye skrini yako na vikomo hivyo huondoka pale amri inapokamilika. Sifa yoyote kutoka systemd.resource-control hufanya kazi baada ya -p.

Kwa kazi ndefu, ondoa --scope na uipe jina. Kisha huendeshwa kwa nyuma kama huduma ya muda mfupi na kuingiza logi kwenye journal:

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

Chaguzi zilezile hufanya kazi na --user wakati wewe si root, ingawa user manager yako ina controllers zilizokabidhiwa kwake pekee, hivyo sifa inaweza kukataliwa huko. Iendeshe na sudo ikiwa hilo litatokea. Kazi inapopata makazi ya kudumu, mipangilio hiyo huhamishwa bila kubadilishwa kwenda kwenye unit halisi: angalia kuendesha script kama systemd service na timer.

Swali la swap, limejibiwa kwa uaminifu

Swap hubadilisha namna ya kutokea kwa hitilafu badala ya kuizuia.

Bila swap, leak ikifika ukomo, kitu fulani hufa ndani ya sekunde chache. Outage hiyo huwa ya ghafla, fupi, na rahisi kusomeka kwenye journal baadaye. Ukiwa na swap, kernel huandika kurasa za anonymous zisizotumika kwenye diski na kupata muda zaidi. Ikiwa mchakato ulikuwa unakaribia kutulia, swap itakuokoa. Ikiwa mchakato unakimbia bila kudhibitiwa, swap hubadilisha outage ya sekunde tano kuwa kukwama kwa dakika ishirini, na kukwama huko ni kubaya zaidi, kwa sababu mchakato uliokufa bado hukuacha na shell inayofanya kazi, wakati seva inayopata thrashing haifanyi kazi.

swapon --show
free -h

Njia ya kati inayofaa kwenye VPS ndogo: weka swap file ya wastani kwa ajili ya kurasa zilizotengwa mara moja na zisizoguswa tena, na uweke MemorySwapMax=0 kwenye vitengo ambavyo uko tayari kupoteza. Huduma muhimu hubaki na swap yao. Zile zisizotabirika hugonga ukuta haraka na kuanza upya.

Kupunguza vm.swappiness ni njia dhaifu, na ni muhimu kujua kwa nini. Inabadilisha tu uwiano kati ya kuondoa page cache na kuhamisha kurasa za anonymous, na zote mbili hugharimu usomaji wa diski baadaye. Inabadilisha ni kurasa zipi zinazopata thrashing, si kama seva itapata thrashing au la.

Daemon ya mapema ya OOM huua kabla ya kukwama

Kernel husubiri hadi mchakato wa reclaim ushindwe kabisa, na kwenye VPS ndogo, muda huo wa kusubiri ndio wakati hasa unapopoteza uwezo wa kuifikia seva. Daemon mbili za userspace hufunga pengo hili kwa kufuatilia kumbukumbu zenyewe na kuua michakato mapema zaidi.

earlyoom hufuatilia kumbukumbu inayopatikana na swap iliyo wazi, na huua mchakato wenye alama ya juu zaidi wakati wowote mojawapo inaposhuka chini ya kiwango kilichowekwa.

sudo apt install earlyoom
systemctl status earlyoom

Kifurushi cha Debian na Ubuntu huanzisha huduma hii wakati wa usakinishaji. Chaguzi zake hupatikana katika /etc/default/earlyoom:

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

-m PERCENT huweka kiwango cha chini cha kumbukumbu inayopatikana na -s PERCENT huweka kiwango cha chini cha swap iliyo wazi, zote zikiwa na asilimia 10 kwa chaguomsingi. Nambari ya pili katika kila jozi ni sehemu ya SIGKILL: earlyoom hutuma SIGTERM pindi unaposhuka chini ya thamani ya kwanza, kisha SIGKILL chini ya ya pili, ambayo kwa chaguomsingi ni nusu ya ile ya kwanza. Tekeleza mabadiliko kwa sudo systemctl restart earlyoom, na usome journalctl -u earlyoom ili kuona ni mchakato gani uliouawa na ni kiasi gani cha kumbukumbu mchakato huo ulikuwa unatumia.

systemd-oomd ndiyo chaguo jingine. Ukurasa wake wa mwongozo unaielezea kama "huduma ya mfumo inayotumia cgroups-v2 na pressure stall information (PSI) kufuatilia na kuchukua hatua za kurekebisha kabla ya OOM kutokea katika nafasi ya kernel". Inafanya kazi kwenye cgroups nzima badala ya michakato binafsi, kwa hivyo huua unit nzima, si mtoto mmoja aliyepotea. Unit hujiunga na huduma hii kwa ManagedOOMMemoryPressure=kill au ManagedOOMSwap=kill, na viwango vya juu (thresholds) hupatikana katika /etc/systemd/oomd.conf.

systemctl status systemd-oomd
oomctl

oomctl huchapisha kile inachofuatilia kwa sasa, ambacho mara nyingi huwa hakuna kitu kwenye image ya seva, kwa sababu mpangilio huu unahitaji kujiunga (opt-in) kwa kila unit. Chagua daemon moja na uishie hapo. Kuendesha zote mbili kunamaanisha vitu viwili vinashindana kuchagua mhasiriwa, na sababu ya mauaji yoyote inakuwa ngumu zaidi kufuatilia.

Ni kitengo kipi kilichohusika?

Anza na kernel, kwa sababu inarekodi kila mchakato inaouua.

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

Uuaji unaofanywa na OOM killer wa mfumo mzima huonekana hivi:

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 ni kumbukumbu ambayo mchakato huo ulikuwa nayo kwenye RAM wakati unakufa, takriban 1.8 GB hapa. Soma jina lililo kwenye mabano kwa tahadhari. Huyo ndiye mhanga aliyechaguliwa na kernel, na kernel huchagua mchakato mkubwa zaidi, ambao si lazima uwe ndio uliosababisha uhaba wa kumbukumbu.

Uuaji unaotokana na kikomo cha cgroup huwa na kiambishi tofauti, na ripoti iliyochapishwa juu yake hutaja cgroup iliyofikia kikomo chake:

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

Kiambishi hicho ni sehemu kubwa ya utambuzi. Memory cgroup out of memory inamaanisha kitengo kimoja kiligonga MemoryMax= uliyokipa na sehemu nyingine ya seva ilikuwa sawa. Out of memory tupu inamaanisha mashine nzima iliishiwa na kumbukumbu, kwa hivyo mipaka yako ilikuwa haipo au ilikuwa kubwa mno kiasi kwamba haikusaidia.

Kisha uliza systemd kile ilichokiona:

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 inasema kitu kilekile kwa mstari mmoja, kama Active: failed (Result: oom-kill).

Kaunta za cgroup ndizo chanzo cha tatu, na ndizo pekee zinazorekodi throttling, ambayo haitoi mstari wowote wa logi:

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 huhesabu mara ngapi kitengo kilisukumwa zaidi ya MemoryHigh= na kupunguzwa kasi (throttled). max huhesabu mara ngapi kilifikia kikomo kigumu (hard cap), na oom_kill huhesabu michakato iliyouawa kweli. high kubwa ikiwa na oom_kill 0 ni kisa cha kimya kilichotajwa awali: huduma inaendelea kufanya kazi, imepunguzwa kasi hadi kutambaa, na haijaripoti hitilafu yoyote kwa mtu yeyote. memory.peak (Linux 5.19 na mpya zaidi) huhifadhi matumizi ya juu zaidi ambayo cgroup ilifikia, ambayo ndiyo namba ya kutumia kupima MemoryMax=. Faili zote mbili hujirekebisha (reset) wakati kitengo kinapoanzishwa upya, kwa sababu systemd hutengeneza cgroup hiyo tena.

Sharti moja lipo chini ya haya yote. Ikiwa /var/log/journal haipo, journal huishi kwenye RAM, na kila mstari hupotea baada ya reboot uliyohitaji ili kuirejesha seva.

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 inayoonyesha zaidi ya boot ya sasa inamaanisha historia sasa inahifadhiwa, kwa hivyo journalctl -k -b -1 inaweza kukuonyesha ujumbe wa kernel kutoka kwenye boot iliyokufa.

Sehemu ya kuanzia kwa VPS ndogo

Kwenye mpango wa 2 GB, acha 300 hadi 400 MB kwa ajili ya kernel na page cache, na usiruhusu jumla ya mipaka (caps) kufikia 2 GB kamili, kwa sababu kila kitengo kinaweza kufikia kilele chake kwa wakati mmoja. Ipe huduma muhimu sehemu kubwa zaidi, kisha wekea mipaka huduma nyingine zote zisizo za lazima zinazoizunguka.

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

Kuweka njia ya kuingia ni muhimu kwa mpangilio mmoja zaidi. OOMScoreAdjust=-500 katika faili ya drop-in ya ssh.service hufanya OOM killer wa mfumo mzima kuwa na uwezekano mdogo wa kuchagua SSH daemon yako kama mhanga, jambo ambalo ni tofauti kati ya kurekebisha seva na kuianzisha upya (reboot) kutoka kwenye control panel. Hii inabadilisha tu chaguo la kernel la nani wa kumuua. Haifupishi muda wa kukwama kwa mfumo.

Containers huendeshwa kwenye cgroups zao wenyewe, zilizoundwa na container runtime badala ya unit files zako, kwa hivyo kikomo kwenye docker.service hakigeuki kuwa kikomo cha container moja. Mambo yanayolingana na MemoryMax= na CPUQuota= kwa kila container yamefafanuliwa katika kuweka mipaka ya kumbukumbu na CPU katika Docker Compose.

FAQ

Kwa nini VPS yangu iliganda badala ya kuua mchakato uliopoteza udhibiti?

Kwa sababu kernel hupima maendeleo kwa kuangalia kama reclaim inarejesha kurasa za kumbukumbu, si kwa muda unaotumika. Kumbukumbu inapopungua, kernel huondoa page cache, ikiwemo kurasa za programu zinazoendelea, kisha huzisoma tena wakati wa maelekezo yanayofuata. Kila kitu husubiri hifadhi na hakuna allocation iliyoshindwa kitaalamu, kwa hivyo OOM killer haiamshwi. Chunguza /proc/pressure/memory wakati tatizo linatokea: full avg10 inayozidi 40 inamaanisha karibu hakuna kazi iliyoweza kufanya kazi katika sekunde kumi zilizopita. Daemon ya userspace kama earlyoom huua mchakato kabla ya seva kufikia hali hiyo.

Kuna tofauti gani kati ya MemoryHigh na MemoryMax?

MemoryHigh= ni kikomo laini (soft cap) kinachopunguza kasi ya matumizi. Kernel hufanya reclaim kwa bidii kutoka kwa unit hiyo na kupunguza kasi ya allocation zake, lakini matumizi yanaweza kuzidi namba hiyo na hakuna kinachouawa. MemoryMax= ni kikomo kigumu (hard cap): allocation inayoshindwa kukamilika chini ya kikomo hiki huamsha OOM killer ndani ya cgroup ya unit hiyo, hivyo mchakato uliosababisha tatizo ndio unaokufa badala ya mchakato mkubwa zaidi kwenye seva. Weka MemoryHigh= chini ya MemoryMax= na chukulia pengo kati yao kama eneo la onyo.

Ninawezaje kujua ni huduma ipi iliyopigwa na OOM killer?

Endesha journalctl -k --grep "Killed process" --since "2 hours ago". Mstari unaoanza na Memory cgroup out of memory unamaanisha unit moja imefikia MemoryMax= yake, wakati Out of memory ya kawaida inamaanisha mashine nzima imekosa kumbukumbu. Kisha endesha journalctl -u <unit> -n 50 na utafute Failed with result 'oom-kill'. Ikiwa /var/log/journal haipo kwenye seva yako, journal ilikuwa imehifadhiwa kwenye RAM na ushahidi ulipotea wakati wa reboot, kwa hivyo tengeneza saraka hiyo kabla ya tukio lijalo.

Je, niongeze swap kwenye VPS ndogo?

Faili ndogo ya swap husaidia kwa kurasa za kumbukumbu (cold pages) ambazo hutengwa mara moja na hazitumiwi tena. Haikusaidii na mchakato uliopoteza udhibiti: huchelewesha kifo cha mchakato na kubadilisha kukatika kwa muda mfupi na kuganda kwa muda mrefu ambako huwezi kuingia ili kurekebisha. Weka swap kwa kiasi kidogo, na uweke MemorySwapMax=0 kwenye unit ambazo uko tayari kuzipoteza, ili zifikie kikomo chake na kuanza upya haraka huku huduma muhimu zikibaki na swap yao.

Je, ninaweza kuzuia amri bila kuandika unit file?

Ndiyo. sudo systemd-run --scope -p MemoryMax=1G -p CPUQuota=50% ./script.sh huendesha amri kwenye terminal yako ndani ya transient scope yenye vikomo hivyo, na vikomo hivyo hupotea amri ikimaliza. Kila sifa kutoka systemd.resource-control inapatikana baada ya -p, kwa hivyo MemorySwapMax=, TasksMax= na CPUWeight= hufanya kazi huko pia. Ondoa --scope na uongeze --unit=name ili kuendesha kazi hiyo kwa nyuma (background) huku matokeo yake yakiwa kwenye journal.