Przejdź do treści
Lekcja 21 z 117

Kurs › Moduł 2 › Lekcja 21

top: co ten ekran w ogóle mówi

⏱ ok. 12 min czytania· moduł 2: Procesy i jak działa system

Po tej lekcji: kursant czyta cały ekran top od góry do dołu: load average w odniesieniu do liczby rdzeni, stany procesora us, sy, wa, st, pamięć z avail, kolumny VIRT, RES, SHR, używa najważniejszych klawiszy i wyciąga dane z top -b -n 1 w skryptach.

Wstęp

Sobota rano. Monitoring przysyła: „load average 6.49”. Kolega z zespołu od razu pisze: „Sześć i pół! Serwer się pali!”. Drugi odpisuje: „Spoko, u nas na bazie zawsze jest koło dwudziestu”.

Który ma rację? Oboje mogą mieć. Albo żaden. Bo ta liczba sama z siebie nic nie znaczy. Dziś dowiesz się, z czym ją porównać, i rozszyfrujemy cały ekran top od góry do dołu. Każdą literę.

top: film zamiast zdjęcia

ps robił zdjęcie kuchni. top włącza kamerę. Ten sam obraz, ale odświeżany co trzy sekundy, posortowany od najbardziej zapracowanego.

top

Wychodzisz klawiszem q. top jest na każdym Linuksie, i na Ubuntu, i na RHEL, bo należy do tego samego pakietu co ps: procps. Na Ubuntu pakiet nazywa się procps, na RHEL procps-ng. Na egzaminie i na obcym serwerze nie licz na nic ładniejszego. top jest zawsze.

Ekran ma dwie części: podsumowanie na górze, pięć linijek, i listę procesów pod spodem. Idziemy od góry.

top - 16:29:54 up 11 min,  0 user,  load average: 6.53, 2.89, 1.14
Tasks: 143 total,   5 running, 138 sleeping,   0 stopped,   0 zombie
%Cpu(s): 38.7 us, 48.4 sy,  0.0 ni,  3.2 id,  0.0 wa,  0.0 hi,  0.0 si,  9.7 st
MiB Mem :   8027.6 total,   5243.5 free,   1128.6 used,   1944.4 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   6899.0 avail Mem

Linijka 1: zegar i load average

Godzina, czas od uruchomienia (up 11 min), liczba zalogowanych użytkowników i trzy liczby, o które wszyscy się kłócą. Te same trzy liczby pokazuje komenda uptime.

Load average, czyli średnie obciążenie. Wyobraź sobie Biedronkę w sobotę. Kasy to rdzenie procesora. Load average to średnia liczba ludzi, którzy są właśnie obsługiwani przy kasie albo stoją w kolejce. Plus ci, którzy stoją przy kasie i czekają, aż kierowniczka przyjdzie z kluczykiem, bo kasa się zawiesiła. Nic nie robią, ale też nie wyjdą.

Te trzy liczby to średnia z ostatniej 1, 5 i 15 minut.

Skąd wiem, że to dokładnie tak? Z dokumentacji. Na Ubuntu 24.04 to man 5 proc_loadavg, na starszych systemach ten sam opis jest w man 5 proc, w części o pliku /proc/loadavg. Pisze tam: liczba zadań w kolejce do uruchomienia, czyli w stanie R, albo czekających na dysk, czyli w stanie D, uśredniona z 1, 5 i 15 minut. Pamiętasz stany z poprzedniej lekcji? Właśnie się przydały.

cat /proc/loadavg
nproc
6.49 2.82 1.11 7/208 10009
2

Pierwsze trzy pola to load average. Czwarte, 7/208, to ile zadań jest gotowych do biegu teraz, a ile istnieje w ogóle, licząc procesy i wątki. Piąte to PID ostatnio utworzonego procesu.

I teraz najważniejsza zasada: load average porównujesz z liczbą rdzeni. nproc mówi, ile ich masz.

  • Load mniejszy niż liczba rdzeni: są wolne kasy.
  • Load równy liczbie rdzeni: wszystkie kasy zajęte, ale bez kolejki.
  • Load wyższy: ludzie stoją w kolejce. Serwer odpowiada wolniej.

Na dwurdzeniowej maszynie load 6.49 to tak, jakby na każdą kasę przypadały ponad trzy osoby. Na serwerze z 32 rdzeniami ta sama liczba znaczy: „mamy dużo wolnego”. Dlatego koledzy z haka mogli mieć obaj rację. Jeden ma dwa rdzenie, drugi czterdzieści.

Te liczby zrobiłem sam. Na moich dwóch rdzeniach odpaliłem cztery procesy, które tylko mieliły procesor:

for i in 1 2 3 4; do timeout 80 yes > /dev/null & done

yes w kółko wypisuje literkę „y”, a my wyrzucamy to do czarnej dziury. Czysty bieg na bieżni. timeout 80 sam je wyłączy po 80 sekundach, żebyś nie musiał sprzątać. Po minucie load dobił do sześciu i pół: cztery yes plus kilka innych rzeczy, które akurat robiła moja maszyna do nagrań.

I drugi trik: czytaj trzy liczby razem. 6.49, 2.82, 1.11 znaczy: minuta temu dużo, kwadrans temu mało. Obciążenie rośnie, coś się właśnie zaczęło. Odwrotnie, 1.1, 2.8, 6.5, znaczy: było źle, ale się uspokaja. Burza mija.

Linijka 2: Tasks

Tasks: 143 total, 5 running, 138 sleeping, 0 stopped, 0 zombie. Ile procesów, w jakim stanie. Wszystko już znasz z poprzedniej lekcji. Jeśli liczba zombie rośnie z dnia na dzień, wiesz, co robić: szukać niechlujnego rodzica.

Linijka 3: na co idzie procesor

To jest linijka, z której doświadczony admin czyta najwięcej. Cały czas procesora podzielony na kawałki, w procentach. Definicje biorę z man top:

  • us — user. Czas na zwykłe programy użytkownika. Kucharze gotują.
  • sy — system. Czas na pracę jądra. Papierologia w biurze kierownika: otwieranie plików, wysyłanie danych przez sieć, przydzielanie pamięci.
  • ni — nice. Programy użytkownika z obniżonym priorytetem. Kucharze, którzy grzecznie ustępują innym. Lekcja o priorytetach już za cztery lekcje.
  • id — idle. Bezczynność. Procesor się nudzi.
  • wa — I/O wait. Czas czekania na dysk albo inne wejście-wyjście. Kucharze stoją i czekają na dostawę.
  • hi i si — przerwania sprzętowe i programowe. Dzwonki do drzwi: karta sieciowa mówi „przyszła paczka”, dysk mówi „gotowe”.
  • st — steal, czyli czas skradziony. Twoja maszyna jest wirtualna, a nadzorca, który dzieli prawdziwy procesor między maszyny, oddał ten czas komuś innemu. Współlokator podbiera Ci palnik w kuchni.

Jak to czytać w praktyce:

  • Wysokie us — aplikacja liczy. Szukaj procesu na górze listy.
  • Wysokie sy — dużo rozmów z jądrem. Na moim ekranie było 48% sy, bo yes wypisuje dane na łeb na szyję, a każdy zapis to prośba do jądra.
  • Wysokie wa — procesor czeka na dysk. Problem jest w dysku, nie w procesorze.
  • Wysokie st — to nie Twoja wina, tylko sąsiadów na tym samym fizycznym serwerze albo dostawcy chmury. U mnie było prawie 10%, bo pracuję na maszynie wirtualnej, która dzieli sprzęt z innymi.

Wciśnij 1, a zamiast jednej linijki zobaczysz osobną dla każdego rdzenia. Przydaje się, kiedy program używa tylko jednego rdzenia: całość mówi „50%”, a w rzeczywistości jeden rdzeń jest na 100%, a drugi śpi.

Linijki 4 i 5: pamięć

MiB Mem :   8027.6 total,   1740.5 free,   1421.5 used,   5279.2 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   6606.0 avail Mem
  • total — cały RAM.
  • free — pamięć zupełnie pusta, nieużywana do niczego.
  • used — używana. W tej wersji top liczona jako całość minus pamięć dostępna.
  • buff/cache — bufory i pamięć podręczna, czyli kopie plików z dysku trzymane w RAM-ie na zapas.
  • avail Mem — ile pamięci można dać nowym programom bez sięgania po swap. To jest najważniejsza liczba.

Zobacz: free 1740, avail 6606. Gdzie reszta? W cache. Linux bierze wolną pamięć i trzyma w niej ostatnio czytane pliki, żeby następnym razem nie czytać ich z dysku. Ale jak program poprosi o pamięć, Linux natychmiast tę cache oddaje. To jak stół w stołówce zastawiony tacami, które sprzątaczka zabiera, gdy tylko ktoś chce usiąść. Stół wygląda na zajęty, ale miejsce jest.

Nowi admini patrzą na free, widzą małą liczbę i panikują, że „Linux zjadł im RAM”. Patrz na avail. Pusta pamięć to zmarnowana pamięć.

Druga linijka to swap: miejsce na dysku, które udaje RAM, kiedy RAM-u brakuje. U mnie zero, bo maszyna nie ma swapa. Na Twojej pewnie będzie. Swap ma swoją opowieść w lekcji o pamięci.

Lista procesów: kolumny

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
20238 root      20   0    2740   1648   1512 R  25.0   0.0   0:15.12 yes
  • PID, USER — numer i właściciel.
  • PR i NI — priorytet i wartość nice. Niższe NI to wyższy priorytet. Szczegóły za cztery lekcje.
  • VIRT — cała pamięć wirtualna procesu: kod, dane, biblioteki, rzeczy zarezerwowane, ale jeszcze nieużyte. To ta sama rezerwacja stolika co VSZ w ps. Może być ogromna i nic nie znaczyć.
  • RES — pamięć rezydentna, czyli to, co proces naprawdę zajmuje w fizycznym RAM-ie. W ps to RSS. Na to patrzysz.
  • SHR — część RES, którą mogą dzielić inne procesy, na przykład biblioteki wspólne. Jak ekspres do kawy w biurze: stoi u Ciebie na biurku, ale korzysta z niego całe piętro. Dlatego zsumowanie RES wszystkich procesów daje więcej niż prawdziwe zużycie.
  • S — stan: R, S, D, T, Z, I.
  • %CPU — ile procesora proces zużył od ostatniego odświeżenia. Może być więcej niż 100%. Program z czterema wątkami na czterech rdzeniach pokaże 400%. To nie błąd, to kucharz z czterema parami rąk.
  • %MEM — RES jako procent całego RAM-u.
  • TIME+ — całkowity czas procesora od startu procesu, z setnymi sekundy.
  • COMMAND — nazwa. Klawisz c przełącza na pełną komendę z argumentami.

Klawisze, które warto znać

  • P — sortuj po procesorze, domyślnie. M — po pamięci. T — po czasie. N — po PID. Wielkie litery, z Shiftem.
  • 1 — osobna linijka na każdy rdzeń.
  • c — pełna komenda zamiast samej nazwy.
  • u — tylko procesy wybranego użytkownika.
  • o — filtr, na przykład COMMAND=sleep.
  • V — widok drzewa, jak pstree.
  • H — pokaż wątki zamiast procesów.
  • k — zabij proces. Pyta o PID, a potem o sygnał, domyślnie SIGTERM. Więcej o sygnałach za dwa lekcje.
  • r — zmień priorytet procesu.
  • d — zmień częstotliwość odświeżania, domyślnie 3 sekundy.
  • E i e — jednostki pamięci w podsumowaniu i na liście: kilobajty, megabajty, gigabajty.
  • f — wybór kolumn. W — zapisz ustawienia na stałe, do pliku w ~/.config/procps/.
  • h — pomoc. q — wyjście.

To samo z linii komend:

top -u eryk
top -p 1234
top -d 1
top -o %MEM

Tylko procesy użytkownika eryk, tylko jeden proces, odświeżanie co sekundę, sortowanie po pamięci.

top -b -n 1: top w skryptach

Interaktywny top w skrypcie jest bezużyteczny. Skrypt nie ma oczu. Ale top ma tryb wsadowy:

top -b -n 1 -o %MEM | sed -n '7,10p'
top -b -n 3 -d 1 | grep '^%Cpu'
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 2950 eryk      20   0 3218764 412880 154212 S  27.3   5.1   2:34.23 firefox
 2411 eryk      20   0 4392116 287316 121044 S   0.0   3.5   0:41.16 gnome-shell
  812 root      20   0 1874528  38212  21056 S   0.0   0.5   0:01.11 snapd
%Cpu(s):  9.1 us,  0.0 sy,  0.0 ni, 86.4 id,  0.0 wa,  0.0 hi,  4.5 si,  0.0 st
%Cpu(s):  3.1 us,  0.9 sy,  0.0 ni, 93.3 id,  0.0 wa,  0.0 hi,  1.3 si,  1.3 st
%Cpu(s): 12.6 us,  4.5 sy,  0.0 ni, 78.9 id,  0.5 wa,  0.0 hi,  1.5 si,  2.0 st
  • -b — batch, tryb wsadowy. Zwykły tekst zamiast odświeżanego ekranu, więc można go puszczać rurą.
  • -n 1 — ile razy odświeżyć i skończyć. Jedno zdjęcie.
  • -n 3 -d 1 — trzy pomiary co sekundę. Dobre do szybkiego sprawdzenia, czy to był chwilowy skok.
  • -w 200 — szersze linijki, żeby długie komendy się nie ucinały.

Najpraktyczniejsze zastosowanie: zrzut stanu serwera do pliku w chwili awarii, żeby potem było co analizować. Do tego wrócimy w module o skryptach i cronie.

Jak to działa pod spodem

top nie ma żadnego specjalnego dostępu do jądra. Co trzy sekundy czyta te same pliki co ps: /proc/loadavg dla obciążenia, /proc/stat dla czasu procesora, /proc/meminfo dla pamięci i /proc/PID/stat dla każdego procesu. Procenty procesora to różnica między dwoma odczytami. Dlatego top z natury pokazuje, co się działo w ostatniej lekcji czasu, a nie w jednym momencie.

A load average liczy samo jądro. Co kilka sekund liczy, ile zadań jest w stanie R albo D, i miesza tę liczbę z poprzednią średnią. top i uptime tylko to odczytują.

Ściąga flag

KomendaFlaga / klawiszCo robi
top-btryb wsadowy, tekst do rury lub pliku
top-n NN odświeżeń i koniec
top-d Sodświeżanie co S sekund
top-u użytkownikprocesy jednego użytkownika
top-p PIDtylko wskazane procesy
top-o KOLUMNAsortowanie po kolumnie, np. %MEM
top-Hwątki zamiast procesów
top-w Nszerokość linii w trybie wsadowym
topP / M / T / Nsortuj: CPU / pamięć / czas / PID
top1osobno każdy rdzeń
topcpełna komenda
topk / rzabij / zmień priorytet
topV / Hdrzewo / wątki
topWzapisz ustawienia
uptime(bez opcji)sam load average i czas pracy
nproc(bez opcji)liczba rdzeni do porównania z load

⚠ Typowy błąd

Admin widzi w top takie coś:

MiB Mem :   8027.6 total,   1740.5 free,   1421.5 used,   5279.2 buff/cache

I pisze do szefa: „Zostało tylko 1,7 GB z 8, trzeba dokupić RAM”. Albo, co gorsza, znajduje w internecie „magiczną komendę do czyszczenia pamięci” i wrzuca do crona echo 3 > /proc/sys/vm/drop_caches co godzinę.

Efekt: Linux co godzinę wyrzuca z pamięci podręcznej pliki, które trzymał po to, żeby było szybciej. Serwer przez chwilę ma pięknie dużo free i jest wolniejszy, bo wszystko czyta od nowa z dysku. To jak wyrzucanie zakupów z lodówki, żeby lodówka wyglądała na pustą.

Patrz na avail Mem. Tu było 6606 MiB, czyli wszystko w porządku. Problem jest wtedy, gdy avail jest małe, a swap rośnie.

✎ Zadanie

  • Sprawdź, ile masz rdzeni przez nproc, i przeczytaj load average przez uptime albo cat /proc/loadavg.
  • Na maszynie wirtualnej uruchom tyle procesów yes > /dev/null &, ile masz rdzeni, plus dwa. Najlepiej z timeout 120 z przodu, żeby same się wyłączyły.
  • W top obserwuj przez minutę load average i linijkę %Cpu. Włącz widok rdzeni klawiszem 1.
  • Posortuj listę po pamięci, włącz pełne komendy i zapisz ustawienia klawiszem W.
  • Jedną linijką z top -b zapisz do pliku stan.txt pięć procesów zjadających najwięcej pamięci, razem z nagłówkiem tabeli.
Pokaż rozwiązanie
nproc
uptime
for i in $(seq $(( $(nproc) + 2 ))); do timeout 120 yes > /dev/null & done
top
# w top: 1, potem M, potem c, potem W
top -b -n 1 -o %MEM | head -12 > stan.txt

seq z arytmetyką Basha robi listę od 1 do „rdzenie plus dwa”, więc pętla sama dopasuje się do Twojej maszyny. Po minucie load average wyraźnie przekracza liczbę rdzeni. Klawisz W potwierdza zapis:

 Wrote configuration to '/home/eryk/.config/procps/toprc'

A head -12, bo nagłówek top to pięć linijek podsumowania, pusta linijka i nagłówek kolumn. Siedem plus pięć procesów daje dwanaście. Matematyka z podstawówki wreszcie się do czegoś przydała.

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 2950 eryk      20   0 3218764 412880 154212 S   0.0   5.1   2:41.07 firefox

Co dalej

top jest wszędzie, ale jest surowy jak dworcowa ławka. W następnej lekcji htop: kolory, paski, drzewo, filtr, mysz i zabijanie strzałkami. Plus krótko o btop i glances, czyli top w wersji dla osób, które lubią kokpit samolotu.