A kérdés szinte mindig ugyanúgy hangzik: éjjel húsz másodpercig tartott, mire a webhely válaszolt, reggelre pedig magától rendbe jött minden. Nézni már nincs mit — a top az aktuális másodpercre felel, a kérdés viszont hajnali háromra vonatkozik. Az alábbiakban arról lesz szó, mit jelentenek valójában a terhelési számok, melyeket kell közülük párban olvasni, és miért téveszt meg gyakrabban egyetlen mérés, mint amennyit segít.

Load average: három szám és egy gyakori félreértés

uptime
cat /proc/loadavg
nproc

A három szám egy, öt és tizenöt perces átlag. Nem a nullához kell hasonlítani őket, hanem a magok számához, amelyet az nproc ír ki. A 8-as érték egy nyolcmagos gépen teljes, de egészséges terhelés: pontosan annyi munka van, amennyit a kiszolgáló el tud végezni. A 2-es érték egy egymagos VPS-en kétszer olyan hosszú sor, mint a kapacitás, és minden kérés kivárja a sorát.

A három szám egymáshoz viszonyított aránya adja meg az irányt. Az egyperces érték jóval a tizenöt perces fölött azt jelenti, hogy a terhelés éppen most emelkedik. Fordítva azt, hogy a csúcs már elmúlt, és csak a végét látja.

Most pedig az a félreértés, amely a leginkább elrontja ezeknek a számoknak az olvasását. A load average Linuxon nem „processzorkihasználtság”. Más Unix rendszerektől eltérően a Linux nemcsak a futó vagy futásra kész folyamatokat számolja bele, hanem a D állapotban lévőket is — a megszakíthatatlan alvásban lévőket. Vagyis azokat, amelyek a lemezre vagy egy hálózati fájlrendszerre várnak. Innen ered a 12-es terhelésű kiszolgáló szinte tétlen processzorral: a munka nem halad, mindenki sorban áll.

Processzor vagy lemez

Ennek a két esetnek a szétválasztása az első érdemi lépés:

vmstat 1 5
iostat -x 1 3

A vmstat kimenetében három oszlop számít. Az r azt mutatja, hány folyamat vár a processzorra, a b azt, hány van blokkolva be- és kimenetre várva, a wa pedig azt az időarányt, amelyet a processzor tétlenül, a lemezre várva töltött. A tartósan 10–15 % fölötti wa szerény us és sy mellett azt jelenti, hogy a kiszolgálót a lemez fogja vissza: magokat hozzáadni értelmetlen, a meglévők amúgy is szabadok.

Hogy melyik folyamat vár, névről kilistázható:

ps -eo state,pid,comm,wchan:30 | awk '$1 ~ /^D/'

Egy példa a saját gyakorlatunkból. Az alapértelmezett beállításokkal a Suricata mintegy harmincféle eseményt ír, és semmilyen rotációt nem állít be hozzájuk — egy éles kiszolgálón ez két nap alatt 15 GB naplót eredményezett. A terhelés eközben nem leterhelt processzorként jelentkezett, hanem éppen I/O waitként: a rendszer szüntelenül írt, és minden más mögötte állt sorban. Az orvosság nem nagyobb csomag, hanem rövidebb eseménylista és beállított rotáció.

A fordított eset, tisztán processzorfüggő és jóval kevésbé kézenfekvő. Egy weboldal azzal a felhasználóval hívta meg az apt parancsot, amellyel a PHP-FPM fut. A root bináris gyorsítótárat tart a /var/cache/apt/pkgcache.bin fájlban — egy tucatnyi tárolóval rendelkező gépen ez 70 MB —, és ingyen leképezi a memóriába. Egy közönséges felhasználó nem írhat abba a könyvtárba, és minden híváskor újraépíti a gyorsítótárat. Ugyanazon a gépen mérve: 0,01 másodperc processzoridő rootként, szemben a 4,2 másodperccel jogosultság nélküli felhasználóként. Ugyanaz a parancs, négyszázszoros különbség, megszorozva minden egyes oldalmegnyitással.

A két esetből ugyanaz a következtetés adódik: a terhelést mérni kell, nem találgatni. Külön-külön megmérni minden gyanús parancsot fél órát vesz igénybe, és rendszerint máshová mutat, mint ahonnan a gyanú indult.

Memória: a free nem azt mutatja, aminek látszik

free -h

A used oszlop önmagában nagyon keveset mond, a free oszlop pedig kifejezetten félrevezet: a Linux a fel nem használt memóriát a lapgyorsítótárnak adja, és az első kérésre visszaadja az alkalmazásoknak. Az olvasandó oszlop az available — mennyit lehet lefoglalni anélkül, hogy swapre kerülne a sor. A nagy buff/cache nem probléma, hanem annak a jele, hogy a rendszer úgy működik, ahogy kell.

A swapnél nem a pillanatnyi érték számít, hanem az alak. Felment, majd visszatért nullára: rövid csúcs volt. Egyszer felment és ott maradt: a csúcs már megvolt, lapok kiszorultak, és senki nem hozza vissza őket — a kiszolgáló nyugodtnak látszik, pedig egy ponton kevés volt a memória. Hogy éppen most zajlik-e a lapozás, azt a vmstat si és so oszlopa mutatja; a nullától eltérő értékek ott a lassulásnak azt a formáját jelentik, amelyet a felhasználók a legjobban megéreznek.

Ha az éjszakai visszaesés alatt egy folyamat egyszerűen eltűnt, a magyarázat rendszerint itt van:

journalctl -k --since yesterday | grep -i "out of memory"
dmesg -T | grep -i "killed process"

Az Out of memory: Killed process 1234 (mysqld) alakú sor bármelyik grafikonnál jobban lezárja a kérdést: az adatbázis nem „magától esett össze”, a kernel állította le, mert elfogyott a memória.

Ki okozza

ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10

Egy fenntartás: a ps %CPU értéke a folyamat teljes élettartamára vett átlag, így egy rövid kiugrás elvész abban a listában. Ahhoz a top vagy a pidstat 1 5 kell, amelyek egy időszakra mérnek.

Mikor lesz a terhelésből biztonsági kérdés

Az éjszakai egyenletes 100 %-os processzorhasználat, mellette semmitmondó nevű folyamat, amelynek munkakönyvtára a /tmp vagy a /dev/shm, a bányász klasszikus képe, nem pedig egy megnőtt webhelyé. A bejövő forgalom kiugrása a naplóírás növekedésével együtt folyamatban lévő jelszótámadás. A hirtelen megugró naplómennyiség rendszerint valamelyik szűrő téves riasztásainak vihara.

Külön kategóriát alkotnak maguk a védelmi eszközök. Az egyik kiszolgálónkon a terhelés három körül maradt egyetlen látogató nélkül is, és a ps élén a felhalmozott processzoridő szerint nem a webhely és nem az adatbázis állt, hanem a CrowdSec, a fail2ban, a Falco és a Suricata. Ez nem hiba, és nem ok a kikapcsolásukra, de a védelem árát érdemes számokban ismerni: egy kis VPS-en érezhető.

Mire jó a megfigyelés

Minden eddigi arra a kérdésre válaszol, hogy „mi történik most”. A reggeli kérdést — mi történt hajnali háromkor — ezek a parancsok nem fedik le: az elmúlt éjszakáról nincs adat, ha senki nem rögzítette. Prometheust és Grafanát felállítani egyetlen VPS kedvéért pedig kétséges, mert a megfigyelő rendszer nehezebbre sikerül, mint a megfigyelt kiszolgáló.

Elég ötpercenként egy sor egy adatbázisban és egy oldal, amely ebből kirajzolja az elmúlt huszonnégy órát: load average, processzorkihasználtság és külön I/O wait, memória és swap, lemezolvasás és -írás, a partíció telítettsége, inode-ok, fájlleírók, kapcsolatok. Egyetlen időtengelyen a párok szabad szemmel is olvashatók: magas wa nyugodt processzor mellett, swap, amely soha nem tért vissza nullára, a határhoz közelítő leírók — a közelgő too many open files hiba órákkal azelőtt láthatóvá válik, hogy bekövetkezne. Hogy mindez összeállítva hogyan néz ki, azt az alábbi bemutatóoldal mutatja meg.