Die Festplattenauslastung ermitteln

Es gibt Dinge, die werden besser, je älter sie werden. Computer gehören definitiv nicht dazu, denn die haben immer das selbe Problem: In dem Moment wo ein neuer Rechner über den Laden geht, ist dieser schon veraltet. Jungspund der ich bin, freute ich mich damals wahnsinnig über meine hochmoderne Festplatte mit einer unglaublichen Kapazität von 2 GB und Ultra DMA-Unterstützung.

Das bedeutet, ich hatte eine Festplatte die theoretisch (und auch nur da) 33,3 MB pro Sekunde lesen konnte. Heute gibt es Netzwerkanschlüsse, die mehr Durchsatz liefern. An der Stelle mag ich es aber mit den Sentimentalitäten belassen, denn der IDE-Standard ist Geschichte und auf den Servern findet man heutzutage zumindest SATA-Festplatten oder gar SAS. Und auch diese Technologien stoßen an Grenzen, insbesondere auf stark beanspruchten Servern wie Datenbanken oder Imageservern.

Das eigentliche Problem kennt jeder: der Server (oder auch Heim-PC) ist überlastet, die Ursache hingegen will erst gefunden werden. Es gibt verschiedene Kenndaten, die Festplatte ist nur eine davon. Linux bringt (insbesondere auf neueren 2.5 und 2.6 Kerneln) eine sehr brauchbare Unterstützung mit, hier mächtige Diagnosekriterien zu finden.

Auslastung & Leistung

Datenbankserver neigen dazu, ständig überlastete Festplatten zu haben. Doch ob eine Festplatte überlastet ist, gilt es erst herauszufinden. Dazu gibt es für Linux sysstat. Das ist eine handvoll hilfreicher Diagnoseprogramme, zum Beispiel pidstat. Dies ermittelt die Festplattenausnutzung von konkreten Anwendungen, in meinem Beispiel des Datenbank-Daemons mySQL:

root@schizoid:/home/support# ps -A | grep "mysqld"
 4619 ?        00:00:00 mysqld_safe
 4654 ?        11-06:28:46 mysqld
root@schizoid:/home/support# pidstat -d -w -p 4654
Linux 2.6.XXXX (schizoid.XXXXXXXX)  07/27/2008

03:37:48 PM       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
03:37:48 PM      4654      0.85      0.00      0.00  mysqld

03:37:48 PM       PID   cswch/s nvcswch/s  Command
03:37:48 PM      4654     74.79      2.90  mysqld

Ein modernes Betriebssystem beherrscht Multitasking, das bedeutet, dass viele Anwendungen scheinbar gleichzeitig ausgeführt werden können. Diese Illusion entsteht, indem der Scheduler die verfügbare CPU-Zeit unter den anfragenden Anwendungen aufteilt, indem er einfach jeder Anwendung einen bestimmten Zeitschlitz zuteilt, während dessen diese den jeweiligen Kram machen kann. Im Detail ist das an der Stelle uninteressant, jedoch gibt es grob zwei Möglichkeiten, die den Kernel veranlasst einer Anwendung (hier “mysqld“) die CPU wieder zu entziehen und stattdessen einer anderen Anwendung zuzuteilen (sowas nennt man “Context Switch”):

  1. Freiwillig: Die Anwendung blockiert; das heißt sie wartet auf das Eintreffen von Daten, die von einem Datenträger, Netzwerk, Terminal etc. erwartet werden.
  2. Unfreiwillig: Die verfügbare Zeit, die CPU zu beanspruchen ist abgelaufen.

Letzterer Fall ist (hier) wünschenswert, das hieße es gäbe keinen nennenswerten Datenstau und die Anwendung kann die Daten schnell verarbeiten. Obige Ausgabe zeigt genau dies an: “cswch/s” die freiwilligen Kontext-Switches und “nvcswch/s” eben die unfreiwilligen. Das Ergebnis ist hier eklatant bezeichnend: die allermeiste Zeit der Rechenzeit verbringt mySQL damit auf Daten (Vorsicht: Daten meint hier jede Art von Ein- und Ausgabe, zum Beispiel auch über das Netzwerk) zu warten, immerhin fast 75 mal pro Sekunde. Das Problem ist hier also relativ eindeutig die Festplattenauslastung.

Etwas allgemeiner zeigt dies übrigens auch das allseits bekannte top als kumulierte CPU-Auslastung:

root@schizoid:/home/support# top -p 4654
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
Cpu(s): 26.7%us,  3.5%sy,  0.0%ni, 55.3%id, 10.8%wa,  0.2%hi,  3.6%si,  0.0%st

Das “wa” ist hier eine prozentuelle Angabe des “I/O wait”, also der selben beschrieben Wartezeit auf Daten, während das “us” (das ist “user cpu time”) die eigentliche Rechenzeit meint.

“top” und “pidstat” helfen also dabei, die Verursacher für Plattenlast zu finden, nicht jedoch die effektive Plattenauslastung. Dafür gibt es ein spezialisierteres Programm: iostat.

root@schizoid:/home/support# iostat -d 5 -m -x
Linux 2.6.XXXXX (schizoid.XXXXXXXXX)  07/27/2008

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.60     0.00  218.00   26.40     3.56     0.80    36.57     1.58    6.45   3.54  86.60

Die Ausgabe ist nützlicher, als die nackten Zahlen scheinen. Übersichtlich aufgeschlüsselt wird hier die Festplattenauslastung (hier zu 86,6% - anhand des oben erklärten “IO wait” kalkuliert) auf Lese- und Schreibzugriffe pro Sekunde aufgeschlüsselt. Weiterhin effektiv gelesene/geschriebene MB pro Sekunde. Spannend ist hierbei zunächst wie eine moderne SAS-Platte lediglich 30 MB pro Sekunde lesen und schreiben kann und dennoch weitestgehend ausgelastet sein kann. In der Theorie leistet jede Festplatte mehr, es können also viel größere Daten pro Sekunde bearbeitet werden. In der Praxis hängen die Durchsatzraten allerdings sehr, sehr stark davon ab, wie die Daten physikalisch auf die Platte geschrieben werden können. Festplatten werden nämlich partitioniert, das heißt in Sektoren (oder auf Dateisystemebene in Blöcke) aufgeteilt, die immer am Stück gelesen werden. Sinnigerweise sollte Sektor- und Blockgröße immer gleich groß sein. Obige Zahl unter “avgrq-sz” gibt an, wie viele Sektoren im Durchschnitt pro Zugriff gelesen/geschrieben werden müssen. Diese Zahl ist hier mit fast 37 Sektoren relativ hoch.

Der Grund ist, dass diese Auslastungszahlen weitgehend durch eine Datenbank entstehen. Datenbanken sind sehr große, wenig gestreute einzelne Dateien. Anders ist es zum Beispiel bei Dateiarchiven (Bilder, Textdateien und dergleichen). Je nach Anwendungszweck gibt es also geeignete und ungeeignete Dateisysteme. Für einzelne große Dateien (wie Datenbanken) bietet sich daher zum Beispiel XFS an, wobei da auch eine viel größere Sektorgröße gewählt werden kann. Erhält man Ausgaben wie oben, kann man die Sektorgröße also durchwegs verfielfachen und damit viel bessere Performance erreichen.

Für viele, kleine hierarchisch verschachtelte Dateien ist hingegen womöglich ReiserFS (Version 4) eine gute Idee.

Eine weitere bedrohliche Zahl sind die 218 Lesezugriffe pro Sekunde wobei nur 0,6 davon zusammengefasst werden konnten, weil sich die Lesezugriffe auf aneinander anschließende Blöcke bezogen. Diese liegen nämlich in den seltensten Fällen in direkt aneinander anschließenden Blöcken, soll heißen die Festplatte ist viel damit beschäftigt den Schreib-/Lesekopf an die richtige Position zu bewegen. Hier schafft das berühmte Defragmentieren Abhilfe. Jeder Windows-Benutzer kennt das und Linux-Nazis behaupten, ihre Dateisysteme würden nicht fragmentieren. Das ist nämlich schlichtweg falsch und kommt vermutlich aus der tatsächlich wahren Tatsache, dass jedes beliebige Linux-Dateisystem weniger fragmentiert als beispielsweise FAT32 oder NTFS. Die Vermeidung von Fragmentation ist technisch unmöglich, insofern ist es auch nur logisch, dass auch Linux-Dateisysteme fragmentieren.

Tatsache ist, es gibt für (fast) alle gängigen Dateisysteme Programme die den Fragmentationsgrad des Dateisystems anzeigen. Im Falle von XFS ist zum Beispiel xfs_db eine Hilfe:

root@schizoid:/home/support# xfs_db  -c frag -r /dev/sda3
actual 10688, ideal 462, fragmentation factor 95.68%

Es wäre also bei diesem Dateisystem eine kluge Idee, den Fragmentationsgrad zu verringern und damit die aneinander anschließenden Lesezugriffe zu optimieren. Für XFS gibt es zum Beispiel das Tool “xfs_fsr”, das genau dies tut.

Irgendwann stößt aber auch diese Methode an ihre Grenzen, dann hilft zugegebenermaßen nur noch ein Hardwareupgrade. Aber bis dahin kann man mit Hilfsmitteln wie iostat und pidstat zumindest zielsicher Flaschenhälse suchen.

Kategorien

Eingeordnet unter: , und

Verwandte Artikel

4 Antworten auf »Die Festplattenauslastung ermitteln«

  1. Hi,
    kennst du auch ein Tool um anzuzeigen welches Programm gerade die Festplatte auslastet?

    viele Grüße

    Catscrash - 30. Juli 2008 um 13:24

  2. Ich erwähnte es bereits im Artikel, nimm pidstat:

    $ pidstat -d

    Arno - 30. Juli 2008 um 16:42

  3. Schöner Artikel. Wieder was gelernt. Danke :)

    Sebastian - 30. Juli 2008 um 20:59

  4. interessant ;)

    mal sehen ob ich damit auch meinen vmware-player in den griff bekomme

    chriss - 5. August 2008 um 20:25

Einen Kommentar schreiben