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 (
$ getconf PAGESIZE
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. 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. Kullanabilmek için Ubuntu ve Fedora'da sysstat paketini kurmak gerekli.
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ç. Kullanabilmek için Ubuntu ve Fedora'da iotop paketini kurmak gerek. Ö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. Bunu kullanabilmek için de sysstat paketini kurmak gerekli. 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". Çalışmak için bekleyen süreç sayısı diyelim. Ya süreç IO bekliyor, ya da CPU meşgul, bu sebeple bazı süreçler henüz görevlerini tamamlayamamış.
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
vmstat ile ilgili güzel bir açıklama
şu adreste var.
2019-08-28 Ek: vmstat sonuçlarının grafiğinin çizilmesi ile ilgili güzel bir
proje buldum. git clone ile önce bir klasöre kopyaladım. vmstat değerlerini dosyaya yazabilmek için önce ekranda gördüğümüz sonuçları bir dosyaya yazmak lazım. En basit haliyle
# vmstat 1 > vmstat.txt
ile ekrana basmadan doğrudan dosyaya, ya da hem ekrana hem dosyaya göndermek için
# vmstat 1 | tee vmstat.txt
ile verileri dosyada biriktirdikten sonra clone'ladığımız klasörün içindeki index.html dosyasını browser ile açıp, vmstat.txt dosyasını sürükleyerek browser penceresinin ortasındaki alana bırakmamız, ya da hiç yerele girmeden doğrudan
http://jsargiot.github.io/vmstatly/ adresinden çalışmamız mümkün.
Referanslar:
[1]
www.ufsdump.org/papers/io-tuning.pdf