Linux系統監控之磁碟I/O篇

markzy5201190發表於2012-12-17

   磁碟I/O 子系統是Linux 系統中最慢的部分.這個主要是歸於CPU到物理操作磁碟之間距離(譯註:碟片旋轉以及尋道).如果拿讀取磁碟和記憶體的時間作比較就是分鐘級到秒級,這就像7天和7分鐘的區別.因此本質上,Linux 核心就是要最低程度的降低I/O 數.本章將訴述核心在磁碟和記憶體之間處理資料的這個過程中,哪些地方會產生I/O.

1.1 讀和寫資料 - 記憶體頁 

Linux 核心將硬碟I/O 進行分頁,多數Linux 系統的預設頁大小為4K.讀和寫磁碟塊進出到記憶體都為4K 頁大小.你可以使用time 這個命令加-v 引數,來檢查你係統中設定的頁大小:
# /usr/bin/time -v date
Page size (bytes): 4096 

1.2 Major and Minor Page Faults(譯註:主要頁錯誤和次要頁錯誤)
Linux,類似多數的UNIX 系統,使用一個虛擬記憶體層來對映硬體地址空間.當一個程式被啟動,核心先掃描CPU caches和實體記憶體.如果程式需要的資料在這2個地方都沒找到,就需要從磁碟上讀取,此時核心過程就是major page fault(MPF).MPF 要求磁碟子系統檢索頁並快取進RAM.

一旦記憶體頁被對映進記憶體的buffer cache(buff)中,核心將嘗試從記憶體中讀取或寫入,此時核心過程就是minor page fault(MnPF).與在磁碟上操作相比,MnPF 通過反覆使用記憶體中的記憶體頁就大大的縮短了核心時間.

以下的例子,使用time 命令驗證了,當程式啟動後,MPF 和 MnPF 的變化情況.第一次執行程式,MPF 會更多:
# /usr/bin/time -v evolution
Major (requiring I/O) page faults: 163
Minor (reclaiming a frame) page faults: 5918 

第二次再執行時,核心已經不需要進行MPF了,因為程式所需的資料已經在記憶體中:
# /usr/bin/time -v evolution
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 5581 

1.3 The File Buffer Cache(譯註:檔案快取區) 

檔案快取區就是指,核心將MPF 過程最小化,MnPF 過程最大化.隨著系統不斷的產生I/O,buffer cache也將不斷的增加.直到記憶體不夠,以及系統需要釋放老的記憶體頁去給其他使用者程式使用時,系統就會丟棄這些記憶體頁.結果是,很多sa(譯註:系統管理員)對系統中過少的free memory(譯註:空閒記憶體)表示擔心,實際上這是系統更高效的在使用caches. 

以下例子,是檢視/proc/meminfo 檔案:
# cat /proc/meminfo
MemTotal: 2075672 kB
MemFree: 52528 kB
Buffers: 24596 kB
Cached: 1766844 kB 

可以看出,這個系統總計有2GB (Memtotal)的可用記憶體.當前的空閒記憶體為52MB (MemFree),有24 MB記憶體被分配磁碟寫操作(Buffers),還有2.7 GB頁用於讀磁碟(Cached). 

核心這樣是通過MnPF機制,而不代表所有的頁都是來自磁碟.通過以上部分,我們不可能確認系統是否處於瓶頸中. 

1.4 Type of Memory Pages 

在Linux 核心中,memory pages有3種,分別是: 

1,Read Pages - 這些頁通過MPF 從磁碟中讀入,而且是隻讀.這些頁存在於Buffer Cache中以及包括不能夠修改的靜態檔案,二進位制檔案,還有庫檔案.當核心需要它們時,將讀取到記憶體中.如果記憶體不足,核心將釋放它們回空閒列表中.程式再次請求時,則通過MPF 再次讀回記憶體. 

2,Dirty Pages - 這些頁是核心在記憶體中已經被修改過的資料頁.當這些頁需要同步回磁碟上,由pdflush 負責寫回磁碟.如果記憶體不足,kswapd (與pdflush 一起)將這些頁寫回到磁碟上並釋放更多的記憶體. 

3,Anonymous Pages - 這些頁屬於某個程式,但是沒有任何磁碟檔案和它們有關.他們不能和同步回磁碟.如果記憶體不足,kswapd 將他們寫入swap 分割槽上並釋放更多的記憶體("swapping" pages). 

1.5 將資料頁寫回磁碟 

應用程式有很多選擇可以寫髒頁回磁碟上,可通過I/O 排程器使用 fsync() 或 sync() 這樣的系統函式來實現立即寫回.如果應用程式沒有呼叫以上函式,pdflush 程式會定期與磁碟進行同步. 

# ps -ef | grep pdflush
root 186 6 0 18:04 ? 00:00:00 [pdflush] 

2.0 監控 I/O 

當覺得系統中出現了I/O 瓶頸時,可以使用標準的監控軟體來查詢原因.這些工具包括了top,vmstat,iostat,sar.它們的輸出結果一小部分是很相似,不過每個也都提供了各自對於效能不同方面的解釋.以下章節就將討論哪些情況會導致I/O 瓶頸的出現. 

2.1 Calculating IO's Per Second(譯註:IOPS 的計算) 

每個I/O 請求到磁碟都需要若干時間.主要是因為磁碟的盤邊必須旋轉,機頭必須尋道.磁碟的旋轉常常被稱為"rotational delay"(RD),機頭的移動稱為"disk seek"(DS).一個I/O 請求所需的時間計算就是DS加上RD.磁碟的RD 基於裝置自身RPM 單位值(譯註:RPM 是Revolutions Perminute的縮寫,是轉/每分鐘,代表了硬碟的轉速).一個RD 就是一個碟片旋轉的 

半圓.如何計算一個10K RPM裝置的RD 值呢:


1, 10000 RPM / 60 seconds (10000/60 = 166 RPS)

2, 轉換為 166分之1 的值(1/166 = 0.006 seconds/Rotation) 

3, 單位轉換為毫秒(6 MS/Rotation)

4, 旋轉半圓的時間(6/2 = 3MS) 也就是 RD

5, 加上平均3 MS 的尋道時間 (3MS + 3MS = 6MS)

6, 加上2MS 的延遲(6MS + 2MS = 8MS) 

7, 1000 MS / 8 MS (1000/8 = 125 IOPS)

每次應用程式產生一個I/O,在10K RPM磁碟上都要花費平均 8MS.在這個固定時間裡,磁碟將盡可能且有效率在進行讀寫磁碟.IOPS 可以計算出大致的I/O 請求數,10K RPM 磁碟有能力提供120-150 次IOPS.評估IOPS 的效能,可用每秒讀寫I/O 位元組數除以每秒讀寫IOPS 數得出.

2.2 Random vs Sequential I/O(譯註:隨機/順序 I/O)

per I/O產生的KB 位元組數是與系統本身workload相關的,有2種不同workload的型別,它們是sequential和random. 

2.2.1 Sequential I/O(譯註:順序IO) 

iostat 命令提供資訊包括IOPS 和每個I/O 資料處理的總額.可使用iostat -x 檢視.順序的workload是同時讀順序請求大量的資料.這包括的應用,比如有商業資料庫(database)在執行大量的查詢和流媒體服務.在這個workload 中,KB per I/O 的比率應該是很高的.Sequential workload 是可以同時很快的移動大量資料.如果每個I/O 都節省了時間,那就意味了能帶來更多的資料處理. 

# iostat -x 1
avg-cpu: %user %nice %sys %idle
0.00 0.00 52.1 4 42.86
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
/dev/sda 0.00 12892.43 0.00 105.71 0.00 1 06080.00 0.00 53040.00 1003.46 1099.43 3442.43 21.49 280.00
/dev/sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
/dev/sda2 0.00 12852.14 0.00 5.71 0.00 105782.86 0.00 52892.43 18512.00 559.14 780.00 490.00 280.00
/dev/sda3 0.00 34.29 0.00 100.00 0.00 292.14 0.00 148.57 2.97 540.29 594.57 24.00 240.00
avg-cpu: %user %nice %sys %idle
0.00 0.00 23.53 71.47
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
/dev/sda 0.00 17320.59 0.00 102.94 0.00 142305.88 0.00 71152.94 1382.40 6975.29 952.29 28.57 294.12
/dev/sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
/dev/sda2 0.00 16844.12 0.00 102.94 0.00 138352.94 0.00 69171.47 1344.00 6809.71 952.29 28.57 294.12
/dev/sda3 0.00 471.47 0.00 0.00 0.00 952.94 0.00 1971.47 0.00 165.59 0.00 0.00 271.47

評估IOPS 的效能,可用每秒讀寫I/O 位元組數除以每秒讀寫IOPS 數得出,比如 

rkB/s 除以 r/s 

wkB/s 除以 w/s 

53040/105 = 505KB per I/O 

71152/102 = 697KB per I/O 

在上面例子可看出,每次迴圈下,/dev/sda 的per I/O 都在增加. 

2.2.2 Random I/O(譯註:隨機IO) 

Random的worklaod環境下,不依賴於資料大小的多少,更多依賴的是磁碟的IOPS 數.Web和Mail 服務就是典型的Random workload.I/O 請求內容都很小.Random workload是同時每秒會有更多的請求數產生.所以,磁碟的IOPS 數是關鍵. 

# iostat -x 1 

avg-cpu: %user %nice %sys %idle 

2.04 0.00 92.96 0.00 

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util 

/dev/sda 0.00 633.67 3.06 102.31 24.49 5282.63 12.24 2640.82 288.89 73.67 113.89 22.22 50.00 

/dev/sda1 0.00 5.10 0.00 2.04 0.00 52.14 0.00 28.57 28.00 2.12 55.00 55.00 12.22 

/dev/sda2 0.00 628.57 3.06 100.27 24.49 5224.49 12.24 2612.24 322.50 72.55 122.25 30.63 50.00 

/dev/sda3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 

avg-cpu: %user %nice %sys %idle 

2.15 0.00 92.85 0.00 

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util 

/dev/sda 0.00 42.94 1.45 130.98 52.61 352.69 25.81 3171.34 19.79 2.90 281.32 2.37 15.05 

/dev/sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 

/dev/sda2 0.00 42.94 4.30 130.98 34.41 352.69 12.20 3171.34 22.18 2.90 320.00 8.24 15.05 

/dev/sda3 0.00 0.00 2.15 0.00 12.20 0.00 8.60 0.00 8.00 0.00 0.00 0.00 0.00 

計算方式和之前的公式一致: 

2640/102 = 23KB per I/O

3176/130 = 24KB per I/O 

(譯註:對於順序I/O來說,主要是考慮讀取大量資料的能力即KB per request.對於隨機I/O系統,更需要考慮的是IOPS值) 

2.3 When Virtual Memory Kills I/O 

如果系統沒有足夠的RAM 響應所有的請求,就會使用到SWAP device.就像使用檔案系統I/O,使用SWAP device 代價也很大.如果系統已經沒有實體記憶體可用,那就都在SWAP disk上建立很多很多的記憶體分頁,如果同一檔案系統的資料都在嘗試訪問SWAP device,那系統將遇到I/O 瓶頸.最終導致系統效能的全面崩潰.如果記憶體頁不能夠及時讀或寫磁碟,它們就一直保留在RAM中.如果保留時間太久,核心又必須釋放記憶體空間.問題來了,I/O 操作都被阻塞住了,什麼都沒做就被結束了,不可避免地就出現kernel panic和system crash.

 下面的vmstat 示範了一個記憶體不足情況下的系統: 

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- 

r b swpd free buff cache si so bi bo in cs us sy id wa 

17 0 1250 3248 45820 1488472 30 132 992 0 2437 7657 23 50 0 23 

11 0 1376 3256 45820 1488888 57 245 416 0 2391 7173 10 90 0 0 

12 0 1582 1688 45828 1490228 63 131 1348 76 2432 7315 10 90 0 10 

12 2 3981 1848 45468 1489824 185 56 2300 68 2478 9149 15 12 0 73 

14 2 10385 2400 44484 1489732 0 87 1112 20 2515 11620 0 12 0 88 

14 2 12671 2280 43644 1488816 76 51 1812 204 2546 11407 20 45 0 35 

這個結果可看出,大量的讀請求回記憶體(bi),導致了空閒記憶體在不斷的減少(free).這就使得系統寫入swap device的塊數目(so)和swap 空間(swpd)在不斷增加.同時看到CPU WIO time(wa)百分比很大.這表明I/O 請求已經導致CPU 開始效率低下. 

要看swaping 對磁碟的影響,可使用iostat 檢查swap 分割槽 

# iostat -x 1 

avg-cpu: %user %nice %sys %idle 

0.00 0.00 100.00 0.00 

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util

 /dev/sda 0.00 1761.67 4861.67 1700.00 38933.33 31200.00 19461.67 15600.00 10.68 6521.67 100.56 5.08 3333.33 

/dev/sda1 0.00 933.33 0.00 0.00 0.00 7733.33 0.00 3861.67 0.00 20.00 2145.07 2.37 200.00 

/dev/sda2 0.00 0.00 4833.33 0.00 38661.67 533.33 19333.33 261.67 8.11 373.33 8.07 1.90 82.00 

/dev/sda3 0.00 833.33 33.33 1700.00 261.67 22933.33 133.33 11461.67 13.38 6133.33 358.46 12.35 1961.67 

在這個例子中,swap device(/dev/sda1) 和 file system device(/dev/sda3)在互相作用於I/O. 其中任一個會有很高寫請求(w/s),也會有很高wait time(await),或者較低的服務時間比率(svctm).這表明2個分割槽之間互有聯絡,互有影響. 

2.4 結論

 I/O 效能監控包含了以下幾點: 

1,當CPU 有等待I/O 情況時,那說明磁碟處於超負荷狀態. 

2,計算你的磁碟能夠承受多大的IOPS 數. 

3,確定你的應用是屬於隨機或者順序讀取磁碟.

 4,監控磁碟慢需要比較wait time(await) 和 service time(svctm). 

5,監控swap 和系統分割槽,要確保virtual memory不是檔案系統I/O 的瓶頸. 


ZZ:http://27151.blog.51cto.com/17151/1074466

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26855487/viewspace-751245/,如需轉載,請註明出處,否則將追究法律責任。

相關文章