Wenn ein System langsam reagiert, muss es nicht immer ein CPU hungriger Prozess sein, der daran schuld ist. Oft ist es auch eine extreme IO-Last, die ein System in die Knie zwingen kann. Das Paket sysstat (Debian) bietet hierfür einige Tools, anhand derer man die IO-Last pro block device und Prozess anzeigen lassen kann.
apt-get install sysstat
iostat
Iostat ist der Kandidat, der die IO-Last pro block device anzeigt.
$ iostat Linux 2.6.28-1-686-bigmem (debian) 11.08.2010 _i686_ avg-cpu: %user %nice %system %iowait %steal %idle 0,72 0,00 0,89 6,52 0,00 91,86 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn sda 34,06 701,10 86,25 385667 47448 sda1 33,98 699,28 86,25 384666 47448 sda2 0,01 0,01 0,00 6 0 sda5 0,04 1,26 0,00 691 0 sdb 3,18 737,33 0,03 405600 16 sdb1 0,11 2,50 0,01 1374 8 sdb2 3,03 734,24 0,01 403898 8
pidstat
pidstat dreht das ganz um und zeigt an, welcher Prozess welche Last verusacht.
$ pidstat -d 2 3 Linux 2.6.28-1-686-bigmem (debian) 11.08.2010 _i686_ 12:43:17 PID kB_rd/s kB_wr/s kB_ccwr/s Command 12:43:19 3310 509,45 0,00 0,00 smbd 12:43:19 PID kB_rd/s kB_wr/s kB_ccwr/s Command 12:43:21 3310 576,00 0,00 0,00 smbd 12:43:21 PID kB_rd/s kB_wr/s kB_ccwr/s Command 12:43:23 1042 0,00 2,00 0,00 kjournald 12:43:23 3310 576,00 0,00 0,00 smbd Durchschn.: PID kB_rd/s kB_wr/s kB_ccwr/s Command Durchschn.: 1042 0,00 0,67 0,00 kjournald Durchschn.: 3310 553,74 0,00 0,00 smbd
Was uns nun noch fehlt, ist die Möglichkeit, die Last pro block device auf Prozesse herunter zu brechen. Mit den obigen Angaben, kann man es sich jedoch auch fast schon denken 😉 Um den Prozess jedoch in Echzeit ausfindig machen zu könne, benötogen wir eine andere Informationen, die uns sar liefern kann. Sar zeichnet die IO-Last über einen gewissen Zeitraum auf. Diese Informationen können anschließend Zweckgebunden ausgewertet werden.
Für die Aktivierung der Aufzeichnung, muss in den Dateien vim /etc/cron.d/sysstat und vim /etc/default/sysstat
ENABLED=true
gesetzt werden. Da der Aufzeichnungsintervall in der Datei /etc/cron.d/sysstat auf 10 Minuten gesetz ist, müssen Sie nach der Änderung mind. 10 Minuten warte, damit sar -d entsprechende Werte anzeigt. Nach 10 Minuten sollt es dann aber in etwa so aussehen.
$ sar -d 12:45:01 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 13:35:01 dev8-0 4,67 533,49 371,01 193,54 0,05 9,70 1,77 0,83 13:35:01 dev8-1 4,67 533,49 371,01 193,54 0,05 9,70 1,77 0,83 13:35:01 dev8-2 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 13:35:01 dev8-5 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 13:35:01 dev8-16 4,36 1082,24 0,00 248,40 0,02 4,17 4,16 1,81 13:35:01 dev8-17 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 13:35:01 dev8-18 4,36 1082,24 0,00 248,40 0,02 4,17 4,16 1,81 Durchschn.: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util Durchschn.: dev8-0 14,44 126,30 61,39 12,99 0,16 11,23 4,23 6,11 Durchschn.: dev8-1 14,44 126,30 61,39 12,99 0,16 11,23 4,23 6,11 Durchschn.: dev8-2 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 Durchschn.: dev8-5 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 Durchschn.: dev8-16 4,69 1066,66 0,00 227,66 0,02 4,04 4,03 1,89 Durchschn.: dev8-17 0,00 0,02 0,00 16,00 0,00 8,00 8,00 0,00 Durchschn.: dev8-18 4,68 1066,65 0,00 227,70 0,02 4,04 4,03 1,89
Hier ist zu erkennen, dass dev8-16 bzw. dev8-18 die Devices mit der größten IO-Last sind. Nun interessiert uns, was es für ein block device ist.
$ more /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
14 sound
21 sg
29 fb
116 alsa
119 vmnet
128 ptm
136 pts
180 usb
189 usb_device
251 firewire
252 usb_endpoint
253 bsg
254 rtc
Block devices:
1 ramdisk
259 blkext
7 loop
8 sd
11 sr
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
254 device-mapper
Dies sagt uns also, dass es ein sd (scsi-disk) block device ist, sprich die Festplatte disk8. Nun schauen wir nach, welche Partition es ist.
$ more /proc/partitions
major minor #blocks name
8 0 244198584 sda
8 1 241545276 sda1
8 2 1 sda2
8 5 2650693 sda5
8 16 488386584 sdb
8 17 439450011 sdb1
8 18 48933990 sdb2
Übrigens liefert ls -l /dev/sda* ebenfalls die major und minor Nummer.
$ ls -l /dev/sda* brw-rw---- 1 root disk 8, 0 11. Aug 12:33 /dev/sda brw-rw---- 1 root disk 8, 1 11. Aug 12:34 /dev/sda1 brw-rw---- 1 root disk 8, 2 11. Aug 12:33 /dev/sda2 brw-rw---- 1 root disk 8, 5 11. Aug 12:33 /dev/sda5$ ls -al /dev/sdb* brw-rw---- 1 root disk 8, 16 11. Aug 12:33 /dev/sdb brw-rw---- 1 root disk 8, 17 11. Aug 12:33 /dev/sdb1 brw-rw---- 1 root disk 8, 18 11. Aug 12:33 /dev/sdb2
disk8-18 ist also die /dev/sdb2. Sar -d lieferte jedoch auch disk8-16 zurück, da dies die Festplatte ist. Disk8-18 ist jedoch die entsprechende Partition der Festplatte.
Nachdem wir nun all diese Informationen haben, können wir die Ausgabe von lsof daraufhin filtern.
lsof | grep "8,18" smbd 3310 root 27rR REG 8,18 2996830364 344078 /vmware/datastores/install/CD Images/Windows 2008 R2 Std ENG/Windows 2008 R2 Standard Edition x64 ENG.iso
oder
lsof | grep "8,18" | awk '{print $1" "$2}' | uniq -c | sort -n -r 1 smbd 3310
Das sagt uns also, dass Samba gerade die höchste IO-Last produziert, da ein Windows 2008 Iso-Image vom Server herunter kopiert wird.
Ein Kommentar
Schöner Artikel!