[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Die Sache mit dem Top (was: Load on master.)



After receiving a question from Florian about the meaning of some top/ps
numbers i have written a small explaination. This is in german, but since we
have quite a few german developers i thought i might answer it here. This is
a prposal for an FAQ Article, comments welcome:


Die Sache mit TOP
-----------------

Die Kopfzeilen von TOP lassen einige Rückschluesse auf das System zu:

  9:37pm  up 13 days, 19:11,  9 users,  load average: 0.37, 0.38, 0.36
59 processes: 57 sleeping, 1 running, 1 zombie, 0 stopped
CPU states: 43.7% user, 53.9% system,  0.0% nice,  2.6% idle
Mem:   18992K av,  18468K used,    524K free,  10344K shrd,    816K buff
Swap:  32756K av,  18736K used,  14020K free                  5736K cached

es ist 21:37, das System läuft seit knapp 14 Tagen.

Die Sache mit den Prozessen
---------------------------
[todo: SMP]
load average: 0.37, 0.38, 0.36
59 processes: 57 sleeping, 1 running, 1 zombie, 0 stopped

Der Load-Average gibt die durchschnittliche Systembelastung an. Dabei gibt
es 3 Werte, den Durschnitt in den letzten 60 Sekunden, in den letzten
300 Sekunden und in den letzten 900 Sekunden. Hier werden einfach die Anzahl
der Prozesse gezählt die bereit sind ausgeführt zu werden. Wenn also 30
Sekunden lang kein Prozess bereit war, und dann 30 Sekunden ein Prozess
lauffähig war, so hat das System eine 1-Munten Load von 0.5.

Jetzt ist die Frage, wann ist ein Prozess lauffähig. Linux kennt mehrere
Zustaende für einen Prozess. Die unwichtigten in dieser Betrachtung sind
"stopped"="T"=TASK_STOPPED (tritt ein wenn ein Prozess mit ^Z oder SIGSTP
angehalten wurde, bzw. wenn er getraced wird (debugger, strace). Ein
weiterer Zustand ist "Zombie"="Z"=TASK_ZOMBIE (tritt ein wenn ein Prozess
sich schon beendet hat, aber sein Vater-Prozess garde nicht bereit ist davon
informiert zu werden. In dem Fall lungern ein paar Daten des Prozesses noch
rum (z.B. der Exit-Status).

Die wirklich interessanten Statussen (*grins*) des Kernels sind:
"running"="R"=TASK_RUNNING (immer dann wenn der Prozess grade irgendetwas
berechnet, oder etwas berechnen wuerde wenn er an der Reihe währe) und
"sleeping"="S"=TASK_INTERRUPTINLE (immer dann wenn ein Prozess auf ein
externes Ereignis wartet, wie z.B. das verstreichen einer bestimtmen Zeit
(sleep), die Ankunft eines Zeichens von Netz oder Terminal (select) oder das
lesen von daten (read) von platte oder terminal oder netz oder das schreiben
von daten auf eine volle netzverbindung, ein haengendes terminal, etc). Und
dann gibt es noch den Zustand "swapping"="W"=TASK_SWAPPING. Der ist dann
vorhanden wenn ein Prozess zwar bereit ist abzulaufen, die zugehoerigen
Sepicherseiten aber grade nicht im Ram sondern auf Swap ist. Ein letzter
Status ist "uninterruptible sleep"="D"="TASK_UNINTERRUPTIBLE". In diesen
Status werden Prozesse versetzt durch den Kernel wenn diese einen Befehl
(syscall) abgesetzt haben der grade nicht ausgeführt werden kann, der aber
in Bearbeitung ist und keinesfalls abgebrochen werden darf. Das sind meist
IO-Operationen die auch (wenn nicht z.B. ein schreiben auf ein NFS Laufwerk
wegen Netzfehler schiefgeht) schnell wieder beendet sind.

Bei Linux werden die Prozesse R D und W als "ready to run" angesehen und in
den Load mit aufgenommen. Bei traditionellen Unix Systemen werden meistens
nur die Prozesse die im Status "R" sind gezaehlt. Ein Prozess in einer
Endlosschleife der keine IO hat erhöht bei beiden Systemen den Load um den
Wert 1.

Was hat das für Auswirkungen?

Die Anzahl der Prozesse die auf die Beendigung einer Swap-Anfrage warten,
spiegeln sich nur bei Linux in der Load wieder, d.h. tendenziell ist die
Load bei starker Speichernutzung/kleinem Speicher bei Linux Systemen hoeher
als bei traditionellem Unix. Hat den Vorteil dass eine hohe Load auf ein
belastetets System hinweist, hat den Nachteil, dass die Load nicht mehr für
die CPU Belastung alleine (durch wirklich rechnende Prozesse) steht.

Okay, aber da gibt es noch mehr Zahlen?

CPU states: 43.7% user, 53.9% system,  0.0% nice,  2.6% idle

Die 100% die eine CPU für Rechenzeit übrig hat hat sie in unserem Beispiel
zu 43.7% damit verbracht Berechnungen in Benutzerprogrammen (dazu gehören
auch Systemdaemone wie Serverprozesse) durchzuführen und 53.9% irgendwelche
Dinge im Kernel zu tun (dazu gehört das zeichenweise lesen/schreiben auf
langsame Hardware genauso wie das berechnen der load *gris* oder das
verwalten des Speichers.) 2.6% der Taetigkeit der CPU hat sich darauf
beschränkt nichts zu tun. In diesem Falle führt die CPU (bzw. jede der
CPUs) eine Endlosschleife aus, in der die CPU sogar angehalten wird (mittels
Assembler-Anweisung hlt). nice gibt an wieviel % der Taetigkeiten der CPU
mit User Programmen in prozessen mit niedriger prio war. Besonders
interessant ist bei den Zahlen zum einen der Wert system (allerdings scher
zu deuten, kosntant hohe werte sind aber schlecht) und zum anderen der wert
idle. Ein hoher %-satz an idle-zeit ist kein schelchtes zeichen wenn das
system wenig belastet ist. Wenn das System aber belastst ist (load > 0.5)
und trotzdem die CPU oft idle ist, so heisst dies meist, dass das System zu
stark damit beschaeftigt ist auf die Erledingung von Swap anfragen zu
warten. -> zu wenig ram oder zu viele speicherintensive laufende
anwendungen.

Nützlich ist hier auch vmstat:

ecki@lina:~> vmstat 1 3 # schreibe alle sekunde (aber max 3) zeilen
 procs                  memory    swap        io    system         cpu
 r b w  swpd  free  buff cache  si  so   bi   bo   in   cs  us  sy  id
 0 0 0 18616   908  1492  5212   1   0    3    2   14   11   9   5  14
 0 0 0 18616   908  1492  5212   0   0    0    0  237   97  25  23  52
 0 0 0 18616   908  1492  5212   0   0    0    0  169    8  24  17  60

r=running (=R)  b=blocked (S+D) w=waiting (W)
speicher analog zu free: swpd=SwapUsed, free=MemFree, buff=buffer, cache=cache
si/so=anzahl der swap-in/out vorgaenge (wenn diese zahlen gross sind,
	dann werden zuviele prozesse ein und ausgelagert in den swap)
bi/bo=block in/out (gibt die anzahl der datenbloecke an die
	gelesen/geschrieben werden von programmen)
in=anzahl der hardwareinterrupts (hohe werte koennen auf amog laufende
	hardware hinweisen, auf schlechte konfiguration (fifo groesse) oder einfach
	auf stark belastete hardware wie serielle ports oder netzkarte.
	Welcher IRQ hier wie oft vorkommt kann man in /proc/interrupts sehen
cs=context switch (gibt an wieviele prozesse rechenzeit bekommen haben,
	grosse zahlen zeigen dass wenige programme rechnen, sondern eher oft 
	den kernel aufrufen, schlecht fuer die effizienz des systems, aber 
	abhaengig vom anwendungsfall)
us=%user sy=%system %id=idle



Die Sache mit dem Speicher:
---------------------------

Unter Intel Linux ist der Speicher in "Seiten" organisiert. Typischerweise
sind das 4kb große Bereich die verwaltet werden.

Typische Ausgabe von Free auf einem 20MB Rechner:

1root@lina:/var/log# cat /proc/meminfo ; free
        total:    used:    free:  shared: buffers:  cached:
Mem:  19447808 18427904  1019904  9506816  1511424  5160960
Swap: 33542144 19542016 14000128
MemTotal:     18992 kB
MemFree:        996 kB
MemShared:     9284 kB
Buffers:       1476 kB
Cached:        5040 kB
SwapTotal:    32756 kB
SwapFree:     13672 kB
             total       used       free     shared    buffers     cached
Mem:         18992      17992       1000       9300       1476       5040
-/+ buffers/cache:      11476       7516
Swap:        32756      19084      13672
1r

Auf PCs kann nicht immer der ganze RAM genutzt werden. Teilweise zweigt sich
die Hardware etwas von dem RAM ab, oder es kann nicht angesprochen werden.

Dann installiert sich der Kernel beim booten fest im Speicher und belegt
Speicher.

Der verbleibende freie Speicher des PCs erscheint dann als "MemTotal" unter
der Free Ausgabe. Von dem Speicher werden nicht immer alle Seiten genutzt.
Es ist jedoch gut wenn moeglichst viele Seiten genutzt werden. Damit der
Kernel operieren kann braucht er aber einen bestimmten Pool von Seiten die
er sofort anfordern kann. (wird durch /proc/sys/vm/freepages bestimmt). Das
ist MemFree (typischerweise ist der Rechner bei MemFree <= 200 tot). Der
freie und der benutzte Speicher addieren sich zum gesamtspeicher.

Der verfügbare Swap Speicher, also ein Bereich in dem der PC
grade nicht benötigte Seiten auslagern kann wird unter "SwapTotal" angegeben.
Hier handelt es sich um die Summen aller aktiven Swap-Files und
Swap-Partitionen. Die anzahl der benutzten bytes und die anzahl
der freien bytes (SwapFree) zusammengenommen ergeben daher immer den
gesamten Swapspeicher. Bei Linux besteht der virtuelle Speicher aus dem
benutzten Ram, dem benutzten Swap und den Seiten die zwar reserviert, aber
noch nicht benutzt wurden. Bei anderen Unix Systemen ist das etwas anderst,
so wird z.b. unter BSD der virtuelle Speicher durch die Groesse des Swaps
bestimmt, der benutze Ram ist nur ein Fenster auf dem Swap Speicher. Der
Linux Ansatz hat den Vorteil dass PRozesse die sehr verschwenerisch Speicher
reservieren und nicht nutzen weniger schnell an das Limit kommen, haben aber
den Nachteil dass der Fall eintreten kann dass ein Prozess der einen
bestimtmen Speicher schon reserviert hat den doch nicht bekommen kann und
dann sehr unsanft (naemlich beim Zugriff stat bei der Reservierung) bendet
wird.

Der benutzte Speicher ist aufgeteilt in Speicher der von einzelnen Prozessen
verwendet wird, in Speicher der von mehreren Prozessen verwendet wird
(MemShared(*1)), in Zwischenspeicher für Filesysteminformationen "Buffers" 
(inodes, Verzeichnisse und Redirectblöcke) und in den Plattencache "Cached".

Buffer werden vom System sehr schnell bei Veraenderungen auf Platte
geschrieben um hier einen konsistenten Stand der Daten zu haben, der Cache
der Daten auf Platte hingegen kann längere Zeit ohne Abgleich mit der Platte
sein. Die Seiten im Cache die mit der Platte identisch sind nennt man Clean,
der Kernel kann die jederzeit freigeben wenn er Seicher benötigt. Seiten die
noch nicht geschrieben sind werden "dirty" genannt. (wenn eine oder mehrere
Ramdisk verwendet werden, so sind deren belegte Blöcke einfach Cache-Seiten 
die als dirty markiert werden und die kein prozess mit einer festplatte
abgleicht).


(*1) MemShared: dabei ist zu beachten dass in aelteren kernels shared
unterschiedlich berechnet wurde. Bei 3 Prozessen mit jeweils 4k geben alte
kernels 12k shared, neue Kernels hingegen 4k shared zurueck. Beide Zahlen
zusammen bekommt man leider nicht, das Programm "memstat" gibt hier aber
einen guten Anhaltspunkt (Debian Paket). Um die Nutzung des Speichers von
Prozessen besser analysieren zu können kann man "ps max" verwenden, fuer die
Analyse ueber die Veraenderung der Nutzung von Speicher ist eher "vmstat -c"
sinnvoll. Um die aktuelle Blegung der Kernel Speicherseiten sehr genau zu sehen
empfiehlt es sich ein Shift+Scroll auf der Tastatur der Console zu druecken, 
im Kernel-Log erscheint dann eine Auflistung des verwendeten Speichers:

Mem-info:
Free pages:         412kB
 ( 3*4kB 4*8kB 5*16kB 3*32kB 1*64kB 1*128kB = 412kB)
Swap cache: add 183483/183483, delete 51740252/173484, find 166788/9625
Free swap:        13920kB
5120 pages of RAM
117 free pages
372 reserved pages
2108 pages shared
Buffer memory:      884kB
Buffer heads:       914
Buffer blocks:      884
   CLEAN: 296 buffers, 1 used (last=1), 0 locked, 0 protected, 0 dirty
  LOCKED: 525 buffers, 73 used (last=157), 0 locked, 0 protected, 0 dirty
   DIRTY: 34 buffers, 0 used (last=0), 0 locked, 0 protected, 34 dirty
Networking buffers in use          : 5
Network buffers locked by drivers  : 0
Total network buffer allocations   : 2503187
Total failed network buffer allocs : 0
Total free while locked events     : 0
IP fragment buffer size            : 0

Copyright (C) 1998 by Bernd Eckenfels, Germany, ecki@lina.inka.de
-- 
  (OO)      -- Bernd_Eckenfels@Wendelinusstrasse39.76646Bruchsal.de --
 ( .. )  ecki@{inka.de,linux.de,debian.org} http://home.pages.de/~eckes/
  o--o     *plush*  2048/93600EFD  eckes@irc  +497257930613  BE5-RIPE
(O____O)       If privacy is outlawed only Outlaws have privacy


Reply to: