2.07.2012

Linux IO monitoring

VMware Server'ın yüklü olduğu linux sistemde kaynak sorunları yaşamamın üzerine sorunun bellek mi, işlemci mi yoksa disk mi olduğunu anlamaya çalıştım. Ama bu kolay olmadı. Window'da aşina olduğum Performans Monitor benzeri bir araç linux server'da yoktu. Bunun için araştırmaya başladım.

Biraz önbilgi. Linux çekirdeği disk IO'yu sayfalara böler. Birçok sistemde varsayılan sayfa boyutu 4K dır (/usr/bin/time -v date komutu ile çalışan sistemin Page Size boyutunu görebilirsiniz). Linux, fiziksel adres alanı ile eşleştirilen bir "sanal bellek alanı" katmanı kullanır. Bir uygulamanın ihtiyaç duyduğu veri önce CPU cache'inde, daha sonra fiziksel bellekte aranır. Bulunamazsa bir majör sayfa hatası (MPF) oluşur ve aranan veri diskten okunarak RAM'deki tampon belleğe yazılır. Tampon bellekteki verilere erişim çağrıları minör sayfa hatasına (MnPF) sebep olur. Bir uygulamanın ne kadar MPF ve MnPF'ye sebep olduğunu
# /usr/bin/time -v <uygulama_adi>
ile görebiliriz. MPF'ları azaltıp MnPF'ları artırmak için disk erişimlerinde buffer (yazma işlemleri için ayrılan tampon bellek) ve cache (okuma işlemleri için ayrılan tampon bellek) kullanılır. Bir sistemdeki toplam bellek miktarı, kullanılan bellek, buffer ve cache değerlerini
#cat /proc/meminfo
Komutu ile öğrenebiliriz.

Bir sistemde üç tip bellek sayfası vardır:
Read Pages: MPF ile diskten okunan sayfalar. Bellekte read-only olarak tutulur. Kütüphane dosyaları gibi hiç değişmeyecek dosyaların ait verileri içerirler. Çekirdek ihtiyaç duydukça bunları kullanır. Bellek sıkıntısı olması durumunda bir kısmı boş olarak işaretlenir, uygulamalar buradaki verilere tekrar ihtiyaç duyduğunda MPF'lerle onları tekrar belleğe getirir.
Dirty Pages: Bu alandaki veriler çekirdek tarafından değiştirilen verilerdir. Değişiklikler diskteki veriye, pdflush daemon tarafından, yansıtılmak (senkronize edilmek) zorundadır. Bellek sıkıntısı olduğunda buradaki veriler kswapd (ve pdflush) ile diske yazılarak yer açılabilir.
Anonymous Pages: Bu tip bellek alanları bir sürece ait değildir ve diskteki bir dosya ile senkronize edilmezler. Bellek sıkıntısı olduğunda buradaki veriler (kswapd ile) takas bölümüne yazılır.

İlk önce bulduğum araç iostat idi. Cyberciti'de güzelce açıklanmış. Örnek bir kullanım şöyle:

$ iostat -d -x 2 2
Device:  rrqm/s  wrqm/s  r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
fd0      0.00    0.00    0.00  0.00   0.00     0.00     8.00     0.00   10.32  10.32   0.00
sda      0.01    5.92    0.07  4.98   2.88    87.32    17.87     0.69  137.16   1.48   0.75

Device:  rrqm/s  wrqm/s  r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
fd0      0.00    0.00    0.00  0.00   0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda      0.00  1130.00   2.50 28.50 368.00  9268.00   310.84     0.23    7.42   1.77   5.50


iostat'ın parametrelerinden d disk kullanım verilerini, x ise ayrıtılı (eXtended) verileri göstermesini sağlıyor. Sonraki sayılardan ilki kaç saniye arayla tekrar verileri göstereceğini, sonraki ise kaç kez bu işlemi tekrarlayacağını gösteriyor. Ben 2 saniye arayla 2 kez istedim. Gösterilen verilere gelirsek

rrqm/s (Read ReQuests Merged per second): Sanyiede birleştirilmiş okuma istekleri (diskte sıraya alınmış)
wrqm/s (Write ReQuests Merged per second): Saniyede birleştirilmiş yazma istekleri (diskte sıralya alınmış)
r/s (Reads per second): Saniyedeki okuma istekleri
w/s (Writes per second): Saniyedeki yazma istekleri
rsec/s (Read Sectors per second): Saniyede okunan sektör sayısı
wsec/s (Write Sectors per second): Saniyede yazılan sektör sayısı
avgrq-sz (AVeraGe ReQuest sector SiZe ): Diske gelen tüm isteklerin sektör sayısı olarak ortalaması
avgqu-sz (AVeraGe ReQuest QUeue SiZe): Diske gelen tüm isteklerin kuyruk uzunluğu olarak ortalaması
await: Diske gelen tüm isteklerin ortalama (milisaniye) karşılanma süresi (kuyrukta bekleme + işlem)
svctm (SerViCe TiMe): Diske gelen tüm isteklerin ortalama işlem süresi (= await - queue time)
%util (bandwidth utilization): Diskin bant genlişliği kullanımı. %100'e yakın olması sınıra yaklaşılmış demek.

İkinci olarak iotop adındaki araç buldum.iotop varsayılan olarak etkileşimli olarak çalışan, sürekli olarak süreçlerin DISK READ ve DISK WRITE değerlerini görüntüleyen bir araç. Örnek kullanım şöyle:

$ iotop -o

Total DISK READ: 93.45 K/s | Total DISK WRITE: 124.60 K/s

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 2590 be/3 root        0.00 B/s  797.45 B/s  ?unavailable?  [kjournald]
 4203 be/3 root        0.00 B/s 1594.90 B/s  ?unavailable?  [kjournald]
15645 be/2 root        0.00 B/s  797.45 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15649 be/2 root        0.00 B/s  797.45 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15652 be/4 root        0.00 B/s  353.56 K/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15656 be/2 root        0.00 B/s  450.12 K/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15661 be/2 root       17.13 K/s  797.45 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15662 be/2 root        2.34 K/s  797.45 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15663 be/2 root        6.23 K/s  797.45 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15664 be/2 root       58.41 K/s  797.45 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15666 be/2 root        9.35 K/s 1594.90 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15667 be/2 root        0.00 B/s 1594.90 B/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""
15668 be/4 root        0.00 B/s  276.46 K/s  ?unavailable?  vmware-vmx -C /vmacs/TESTM~ndard x64 Edition.vmx -@ ""



Burada SWAPIN ve IO sütunlarının altında ?unavailable? yazmasının sebebini ekranın altındaki

CONFIG_TASK_DELAY_ACCT not enabled in kernel, cannot determine SWAPIN and IO %

hatasıyla açıklamış. Buna göre kernel'i uygun config ile tekrar derlemek gerek. Etkileşimli çalışma kipinde sağ ve sol ok tuşlarını kullanarak verilerin hangi alana göre sıralanacağını seçebiliriz. Seçilen alanın yanında bir ">" işareti belirir. Komut satırında kullandığım -o anahtarı ise sadece I/O yapan süreç ve thread'leri göster demek.

Üçüncü olarak budluğu araç ise vmstat. Ben en çok bunu sevdim. Komut satırından çalıştırırken sadece kaç saniyede bir güncel verileri görüntüleyeceğini seçmek gerekiyordu, 1 ile ben her saniye görüntülemesini belirttim. Durdurana kadar her saniye yeni bir satır ekleyerek verileri tekrar yazıyor:

$ vmstat 1
procs  -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache    si   so    bi    bo   in   cs us sy id wa
 0  1  27800  39548  14796 3500092    0    0  2720     0  145 1991  1  3 88  8
 0  5  27800  36204  14828 3502532    0    0  2644   520  194 2258  0  3 65 32
 0  5  27800  33804  14848 3504596    0    0  2116     4  348 1922  1  3 26 70
 0  1  27800  30848  14892 3506260    0    0  1584     0  232 2508  1  3 71 25
 0  1  27800  26772  14940 3509760    0    0  3396     0  279 2924  1  4 74 21
 0  1  27800  23332  14992 3512740    0    0  3028     0  225 2501  0  4 74 22
 0  3  27800  25696  14984 3508956    0    0  1816   816  239 2168  0  5 59 36
 0  3  27800  25368  15004 3509372    0    0   332  1408  486 1123  0  1 40 59
 0  3  27800  29500  13272 3506900    0    0  1352   344  338 2122  1  2 32 64
 1  2  27800  27004  13284 3509260    0    0  2308     0  230 2060  1  3 53 42
 0  3  27800  30180  13288 3509732    0    0   748     0  152 2104  0  9 66 25
 0  2  27800  25196  13324 3511936    0    0  1888     0  853 2381  3 12 52 33
 1  2  27800  23768  13336 3513756    0    0  1832    48 1285 2756  5  9 60 26


Yukarıda görülen alanların anlamları (veri miktarı birimi KiB)
r (runtime):  "Number of processes waiting for runtime". Runtime ile tam olarak kastedilen ne bilemiyorum, ama "Çalışmayı bekleyen süreç sayısı" diyelim şimdilik.
b (blocked): IO kaynağı eksikliği sebebiyle hizmet verilemeyen thread sayısı (başka bir kaynakta ise bekleme sebebinin IO olmayabileceği yazıyordu).
swpd: Kullanılan sanal bellek miktarı
free: Kullanılmayan bellek miktari
buff: Yazma işlemleri için ayrılan tampon bellek miktarı (RAM)
cache: Okuma işlemleri için ayrılan tampon bellek miktarı (RAM)
si (swap-in): Swap'ten okunan bellek miktarı
so (swap-out): Swap'e yazılan bellek miktarı
bi (block-in): Diskten okunan blok miktarı
bo (block-out): Diske yazılan blok miktarı
in: Saniyede gelen kesme (interrupt) sayısı (saat dahil)
cs: Saniyede yapılan context switching sayısı

Toplam CPU zamanını (% olarak) şöyle açıklayabiliriz:

%CPU zamanı = %Kullanıcı_süreçleri + %Kernel_süreçleri + %Boşta_zaman + %WIO

Buna göre (tümü yüzde olarak):
us: Kullanıcı süreçlerinin işletilmesine harcanan CPU zamanı
sy: Kernel (çekirdek) süreçlerini işletmek için harcanan CPU zamanı
id: Idle. CPU'nun boşta durma zamanı
wa: WIO, ya da wait-IO. CPU zamanın IO işlemlerini beklemek için harcanan kısmı

Artık şöyle yazabiliriz:
%CPU zamanı=us + sy + id + wa

Referanslar:
[1] www.ufsdump.org/papers/io-tuning.pdf

Hiç yorum yok: