Pitanje glasi gotovo uvek isto: noću je sajtu trebalo dvadeset sekundi da odgovori, a do jutra se sve samo popravilo. Nema više šta da se gleda — top odgovara za tekuću sekundu, a pita se za tri sata ujutru. U nastavku sledi šta brojevi opterećenja zaista znače, koje od njih treba čitati u parovima i zašto jednokratno merenje češće zavara nego što pomogne.
Load average: tri broja i jedan čest nesporazum
uptime
cat /proc/loadavg
nproc
Ta tri broja su proseci za jedan, pet i petnaest minuta. Ne porede se sa nulom, već sa brojem jezgara koji prijavljuje nproc. Vrednost 8 na mašini sa osam jezgara je puno, ali zdravo opterećenje: posla ima tačno onoliko koliko server može da obavi. Vrednost 2 na VPS-u sa jednim jezgrom je red dvostruko duži od kapaciteta, i svaki zahtev čeka svoj red.
Odnos ta tri broja pokazuje smer. Jednominutna vrednost osetno iznad petnaestominutne znači da opterećenje raste upravo sada. Obrnuto znači da je vrhunac prošao i da se vidi samo njegov rep.
Sada nesporazum zbog kojeg se ovi brojevi najčešće pogrešno čitaju. Load average na Linuxu nije „iskorišćenost procesora". Za razliku od drugih Unix sistema, Linux u njega ubraja ne samo procese koji se izvršavaju ili su spremni za izvršavanje, već i one u stanju D — u neprekidivom snu. Dakle one koji čekaju disk ili mrežni sistem datoteka. Otuda server sa opterećenjem 12 i gotovo besposlenim procesorom: posao ne napreduje, svi stoje u redu.
Procesor ili disk
Razdvajanje ta dva slučaja je prva stvar koju vredi uraditi:
vmstat 1 5
iostat -x 1 3
U izlazu komande vmstat važne su tri kolone. r je koliko procesa čeka u redu za procesor, b koliko ih je blokirano čekajući ulaz i izlaz, a wa udeo vremena koji je procesor proveo besposlen čekajući disk. Trajno wa iznad 10–15 % uz skromne us i sy znači da se server oslanja o disk: dodavanje jezgara ne pomaže, postojeća su ionako slobodna.
Koji procesi čekaju može se izlistati poimenično:
ps -eo state,pid,comm,wchan:30 | awk '$1 ~ /^D/'
Primer iz sopstvene prakse. Sa podrazumevanom konfiguracijom Suricata upisuje tridesetak tipova događaja i za njih ne podešava nikakvu rotaciju — na radnom serveru to je dalo 15 GB dnevnika za dva dana. Opterećenje se pritom nije ispoljavalo kao zauzet procesor, već upravo kao I/O wait: sistem je pisao bez prestanka, a sve ostalo je stajalo u redu iza njega. Lek nije veći paket, nego kraći spisak tipova događaja i podešena rotacija.
Obrnut slučaj, čisto procesorski i znatno manje očigledan. Veb stranica je pozivala apt pod korisnikom pod kojim radi PHP-FPM. Root drži binarni keš u /var/cache/apt/pkgcache.bin — na mašini sa desetak skladišta to je 70 MB — i mapira ga u memoriju besplatno. Običan korisnik ne sme da piše u taj direktorijum i keš iznova gradi pri svakom pozivu. Mereno na jednoj te istoj mašini: 0,01 sekunda procesorskog vremena kao root prema 4,2 sekunde kao korisnik bez privilegija. Ista komanda, razlika četiristo puta, pomnožena svakim otvaranjem stranice.
Zaključak iz oba slučaja je isti: opterećenje se meri, a ne pogađa. Merenje svake sumnjive komande posebno traje pola sata i obično pokaže na nešto sasvim drugo od onoga odakle je sumnja krenula.
Memorija: free ne pokazuje ono na šta liči
free -h
Kolona used sama po sebi govori vrlo malo, a kolona free direktno zavarava: Linux nezauzetu memoriju daje kešu stranica i vraća je aplikacijama na prvi zahtev. Čita se kolona available — koliko se može zauzeti bez odlaska u swap. Veliki buff/cache nije problem, već znak sistema koji radi kako treba.
Kod swapa nije važna trenutna vrednost, nego oblik. Porastao pa se vratio na nulu: bio je kratak vrhunac. Porastao jednom i tu ostao: vrhunac je već bio, stranice su potisnute i niko ih ne vraća — server deluje mirno, iako mu je u jednom trenutku ponestalo memorije. Da li se razmena odvija upravo sada, pokazuju kolone si i so u vmstat-u; vrednosti različite od nule tamo su onaj oblik usporenja koji korisnici najviše osećaju.
Ako je tokom noćnog pada neki proces jednostavno nestao, objašnjenje je obično ovde:
journalctl -k --since yesterday | grep -i "out of memory"
dmesg -T | grep -i "killed process"
Red poput Out of memory: Killed process 1234 (mysqld) zatvara pitanje bolje od bilo kog grafikona: baza nije „pala sama", zaustavilo ju je jezgro jer je memorija presušila.
Ko to radi
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10
Jedna ograda: %CPU u ps-u je prosek za ceo život procesa, pa se kratak skok u tom spisku izgubi. Za njega su potrebni top ili pidstat 1 5, koji mere u intervalu.
Kada opterećenje postaje pitanje bezbednosti
Ravnih 100 % procesora noću, uz proces sa bezveznim imenom i radnim direktorijumom u /tmp ili /dev/shm, klasična je slika rudara, a ne sajta koji je porastao. Skok dolaznog saobraćaja zajedno sa porastom upisa u dnevnike znači napad na lozinke u toku. Naglo narastao obim dnevnika po pravilu je oluja lažnih uzbuna nekog filtera.
Posebna kategorija su sami zaštitni alati. Na jednom od naših servera opterećenje se držalo oko tri bez ijednog posetioca, a na vrhu ps-a po nakupljenom procesorskom vremenu nisu stajali ni sajt ni baza, nego CrowdSec, fail2ban, Falco i Suricata. To nije kvar niti razlog da se isključe, ali cenu zaštite vredi znati u brojkama: na slabom VPS-u se oseti.
Čemu služi posmatranje
Sve navedeno odgovara na pitanje „šta se dešava sada". Jutarnje pitanje — šta je bilo u tri sata noću — ove komande ne pokrivaju: o protekloj noći nema podataka ako ih niko nije zabeležio. A dizati Prometheus i Grafanu zbog jednog jedinog VPS-a je sporno, jer stek koji posmatra ispadne teži od servera koji se posmatra.
Dovoljan je red u bazi svakih pet minuta i jedna stranica koja iz njega crta poslednja dvadeset četiri sata: load average, iskorišćenost procesora i posebno I/O wait, memorija i swap, čitanje i upis diska, popunjenost particije, i-čvorovi, deskriptori datoteka, veze. Na jednoj vremenskoj osi parovi se čitaju golim okom: visoko wa uz miran procesor, swap koji se nikada nije vratio na nulu, deskriptori koji se približavaju granici — nadolazeća greška too many open files postaje vidljiva satima pre nego što se dogodi. Kako to izgleda sastavljeno, pokazuje demo stranica ispod.