Memoriaz kanpoko hiltzailea Linux-en konfiguratzea PostgreSQL-rako

Memoriaz kanpoko hiltzailea Linux-en konfiguratzea PostgreSQL-rako

Datu-base zerbitzari bat Linux-en ustekabean irteten denean, arrazoia aurkitu behar duzu. Hainbat arrazoi egon daitezke. Adibidez, SIGSEGV β€” hutsegitea backend zerbitzariaren akats baten ondorioz. Baina hau arraroa da. Gehienetan, diskoko lekurik edo memoriarik gabe geratzen zara. Diskoko lekurik gabe geratzen bazara, aterabide bakarra dago: askatu lekua eta berrabiarazi datu-basea.

Memoriaz Kanpoko Hiltzailea

Zerbitzari edo prozesu bat memoriarik gabe geratzen denean, Linuxek 2 irtenbide eskaintzen ditu: sistema osoa huts egin edo memoria jaten ari den prozesua (aplikazioa) amaitzea. Hobe da, noski, prozesua amaitzea eta OSa hutsegitetik salbatzea. Laburbilduz, Out-Of-Memory Killer aplikazio bat hiltzen duen prozesua da nukleoa hutsegitetik salbatzeko. Aplikazioa sakrifikatzen du sistema eragilea martxan mantentzeko. Lehenik eta behin, eztabaida dezagun OOM-ek nola funtzionatzen duen eta nola kontrolatu, eta, ondoren, ikus dezagun nola erabakitzen duen OOM Killer-ek zein aplikazio amaitu.

Linux-en zeregin nagusietako bat prozesuei memoria esleitzea da eskatzen dutenean. Normalean, prozesu edo aplikazio batek memoria eskatzen dio sistema eragileari, baina ez du guztiz erabiltzen. OSak memoria ematen badie eskatzen duten guztiei, baina erabiltzeko asmorik ez badu, oso laster memoria agortuko da eta sistemak huts egingo du. Hori ekiditeko, sistema eragileak memoria gordetzen du prozesurako, baina ez du benetan askatzen. Memoria prozesu batek benetan erabiliko duenean soilik esleitzen da. Gertatzen da OSak ez duela memoria librerik, baina prozesu bati memoria esleitzen diola, eta prozesu batek behar duenean, OSak ahal badu esleitzen du. Alde txarra da batzuetan OSak memoria gordetzen duela, baina une egokian ez dago memoria librerik, eta sistema huts egiten du. OOM-ek paper garrantzitsua jokatzen du eszenatoki honetan eta prozesuak amaitzen ditu nukleoa izua ez dadin. PostgreSQL prozesu bat amaitzera behartzen denean, mezu bat agertzen da erregistroan:

Out of Memory: Killed process 12345 (postgres).

Sistemak memoria gutxi badu eta ezin bada askatu, funtzioari deitzen zaio out_of_memory. Etapa honetan, gauza bakarra geratzen zaio egiteko: prozesu bat edo gehiago osatzea. OOM-killer-ek prozesua berehala amaitu behar al du edo itxaron al dezake? Jakina, out_of_memory deitzen denean, I/O eragiketa baten zain egoteagatik edo diskoan orrialdea izateagatik da. Hori dela eta, OOM hiltzaileak egiaztapenak egin behar ditu lehenik eta, horietan oinarrituta, prozesua amaitu behar dela erabaki. Beheko egiaztapen guztiak positiboak badira, OOM-ek prozesua amaituko du.

Prozesuaren hautaketa

Memoria agortzen denean, funtzioari deitzen zaio out_of_memory(). Funtzio bat du select_bad_process(), funtzioaren ebaluazioa jasotzen duena badness(). Prozesu "txarrena" bideratuko da. Funtzioa badness() arau batzuen arabera prozesu bat hautatzen du.

  1. Nukleoak memoria minimo bat behar du beretzat.
  2. Memoria asko askatu behar duzu.
  3. Ez dago memoria gutxi erabiltzen duten prozesuak amaitu beharrik.
  4. Gutxieneko prozesuak burutu behar dira.
  5. Erabiltzaileak berak burutu nahi dituen prozesu horiek burutzeko aukerak areagotzen dituzten algoritmo konplexuak.

Egiaztapen hauek guztiak amaituta, OOMek puntuazioa aztertzen du (oom_score). OOM esleitzen du oom_score prozesu bakoitza, eta, ondoren, balio hori memoria kopuruarekin biderkatzen du. Balio handiagoak dituzten prozesuek OOM Killer-en biktima gehiago izango dira. Erroko erabiltzailearekin lotutako prozesuek puntuazio baxuagoa dute eta litekeena da amaitzera behartuta egotea.

postgres=# SELECT pg_backend_pid();
pg_backend_pid 
----------------
    3813
(1 row)

Postgres prozesuaren IDa 3813 da, beraz, beste shell batean puntuazioa lor daiteke nukleoaren parametro hau erabiliz oom_score:

vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2

Ez baduzu nahi OOM-Killer-ek prozesua amaitzea, nukleoaren beste aukera bat dago: oom_score_adj. Gehitu balio negatibo handi bat baloratzen duzun prozesu bat amaitzeko aukerak murrizteko.

sudo echo -100 > /proc/3813/oom_score_adj

Balio bat ezartzeko oom_score_adj, ezarri OOMScoreAdjust zerbitzu-blokean:

[Service]
OOMScoreAdjust=-1000

Edo erabili oomprotect talde batean rcctl.

rcctl set <i>servicename</i> oomprotect -1000

Prozesu baten amaiera behartu

Dagoeneko prozesu bat edo gehiago hautatzen direnean, OOM-Killer-ek funtzioari deitzen dio oom_kill_task(). Funtzio honek amaiera-seinalea bidaltzen dio prozesuari. Memoria eskasia izanez gero oom_kill() Funtzio honi deitzen dio SIGKILL seinale bat prozesura bidaltzeko. Mezu bat idazten da nukleoaren erregistroan.

Out of Memory: Killed process [pid] [name].

Nola kontrolatu OOM-Killer

Linux-en, OOM-Killer aktibatu edo desgai dezakezu (azken hau gomendagarria ez den arren). Gaitzeko edo desgaitzeko, erabili parametroa vm.oom-kill. Exekutatu momentuan OOM-Killer gaitzeko, exekutatu komandoa sysctl.

sudo -s sysctl -w vm.oom-kill = 1

OOM-Killer desgaitzeko, zehaztu 0 balioa komando berean:

sudo -s sysctl -w vm.oom-kill = 0

Komando honen emaitza ez da betiko gordeko, lehen berrabiarazi arte baizik. Iraunkortasun gehiago behar baduzu, gehitu lerro hau fitxategira /etc/sysctl.conf:

echo vm.oom-kill = 1 >>/etc/sysctl.conf

Gaitzeko eta desgaitzeko beste modu bat aldagai bat idaztea da panic_on_oom. Balioa beti egiaztatu daiteke /proc.

$ cat /proc/sys/vm/panic_on_oom
0

0 balioa ezartzen baduzu, memoria agortzen denean, ez da nukleoaren izurik izango.

$ echo 0 > /proc/sys/vm/panic_on_oom

Balioa 1ean ezartzen baduzu, memoria agortzen denean, kernel izua sortuko da.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer ez da bakarrik aktibatu eta desaktibatu. Dagoeneko esan dugu Linuxek prozesuetarako eskuragarri dagoena baino memoria gehiago erreserbatu dezakeela benetan esleitu gabe, eta portaera hori Linux kernel-parametro batek kontrolatzen du. Aldagaia da horren erantzule vm.overcommit_memory.

Horretarako balio hauek zehaztu ditzakezu:

0: Nukleoak berak erabakitzen du memoria gehiegi gorde behar duen. Hau lehenetsia da Linux-en bertsio gehienetan.
1: Nukleoak memoria gehigarria gordeko du beti. Arriskutsua da hori, memoria agortu daitekeelako, ziurrenik egunen batean prozesuek hala eskatuko dutelako.
2: nukleoak ez du parametroan zehaztutakoa baino memoria gehiago erreserbatuko overcommit_ratio.

Parametro honekin, gehiegi erreserbatu daitekeen memoriaren ehunekoa zehazten duzu. Tokirik ez badago, ez da memoriarik esleituko, eta erreserba ukatu egingo da. Hau da PostgreSQL-rentzat gomendatutako aukerarik seguruena. OOM-Killer-ek beste elementu batek eragiten du: aldagaiak kontrolatzen duen truke-gaitasuna cat /proc/sys/vm/swappiness. Balio hauek nukleoari orria nola kudeatu esaten diote. Zenbat eta balioa handiagoa izan, orduan eta gutxiago izango da OOM-ek prozesua amaitzea, baina I/O eragiketen ondorioz datu-basean eragin negatiboa du. Eta alderantziz: zenbat eta balioa txikiagoa izan, orduan eta handiagoa da OOM-Killer esku hartzeko aukera, baina datu-basearen errendimendua ere handiagoa da. Balio lehenetsia 60 da, baina datu-base osoa memorian sartzen bada, hobe da balioa 1ean ezartzea.

Emaitzak

Ez utzi OOM-Killer-eko "hiltzaileak" ikaratzen. Kasu honetan, hiltzailea zure sistemaren salbatzailea izango da. Prozesurik txarrenak "hiltzen" ditu eta sistema hondatzetik salbatzen du. PostgreSQL amaitzeko OOM-Killer erabili beharrik ez izateko, ezarri honela vm.overcommit_memory 2. balioa. Horrek ez du bermatzen OOM-Killer-ek esku hartu beharko ez duenik, baina PostgreSQL prozesua amaitzera behartzeko aukera murriztuko du.

Iturria: www.habr.com

Gehitu iruzkin berria