Linux System and Performance Monitoring(I/O篇) 6.0 I/O 監控介紹 磁盤I/O 子系統是Linux 系統中最慢的部分.這個主要是歸於CPU到物理操作磁盤之間距離(譯註:盤片旋轉以及尋道).如果拿讀取磁盤和內存的時間作比較就是分鐘級到秒級,這就像 7天和7分鐘的區別.因此本質上,Linux 內核就是要最低程度的降低I/O 數.本章將訴述內核在磁盤和內存之間處理數據的這個過程中,哪些地方會產生I/O. 6.1 讀和寫數據 – 內存頁 Linux 內核將硬盤I/O 進行分頁,多數Linux 系統的默認頁大小為4K.讀和寫磁盤塊進出到內存都為4K 頁大小.你可以使用time 這個命令加-v 參數,來檢查你系統中設置的頁大小: # /usr/bin/time -v date Page size (bytes): 4096 6.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 6.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),還有1.7 GB頁用於讀磁盤(Cached). 內核這樣是通過MnPF機制,而不代表所有的頁都是來自磁盤.通過以上部分,我們不可能確認系統是否處於瓶頸中. 6.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). 6.5 Writing Data Pages Back to Disk 應用程式有很多選擇可以寫臟頁回磁盤上,可通過I/O 調度器使用 fsync() 或 sync() 這樣的系統函數來實現立即寫回.如果應用程式沒有調用以上函數,pdflush 進程會定期與磁盤進行同步. # ps -ef | grep pdflush root 186 6 0 18:04 ? 00:00:00 [pdflush] 7.0 監控 I/O 當覺得系統中出現了I/O 瓶頸時,可以使用標準的監控軟體來查找原因.這些工具包括了top,vmstat,iostat,sar.它們的輸出結果一小部分是很相似,不過每個也都提供了各自對於性能不同方面的解釋.以下章節就將討論哪些情況會導致I/O 瓶頸的出現. 7.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 數得出. 7.2 Random vs Sequential I/O(譯註:隨機/順序 I/O) per I/O產生的KB 位元組數是與系統本身workload相關的,有2種不同workload的類型,它們是sequential和random. 7.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 57.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 12891.43 0.00 105.71 0.00 1 06080.00 0.00 53040.00 1003.46 1099.43 3442.43 26.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 12857.14 0.00 5.71 0.00 105782.86 0.00 52891.43 18512.00 559.14 780.00 490.00 280.00 /dev/sda3 0.00 34.29 0.00 100.00 0.00 297.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 76.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 69176.47 1344.00 6809.71 952.29 28.57 294.12 /dev/sda3 0.00 476.47 0.00 0.00 0.00 952.94 0.00 1976.47 0.00 165.59 0.00 0.00 276.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 都在增加. 7.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 97.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 5281.63 12.24 2640.82 288.89 73.67 113.89 27.22 50.00 /dev/sda1 0.00 5.10 0.00 2.04 0.00 57.14 0.00 28.57 28.00 1.12 55.00 55.00 11.22 /dev/sda2 0.00 628.57 3.06 100.27 24.49 5224.49 12.24 2612.24 321.50 72.55 121.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 97.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 41.94 6.45 130.98 51.61 352.69 25.81 3176.34 19.79 2.90 286.32 7.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 41.94 4.30 130.98 34.41 352.69 17.20 3176.34 21.18 2.90 320.00 8.24 15.05 /dev/sda3 0.00 0.00 2.15 0.00 17.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值) 7.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 1766.67 4866.67 1700.00 38933.33 31200.00 19466.67 15600.00 10.68 6526.67 100.56 5.08 3333.33 /dev/sda1 0.00 933.33 0.00 0.00 0.00 7733.33 0.00 3866.67 0.00 20.00 2145.07 7.37 200.00 /dev/sda2 0.00 0.00 4833.33 0.00 38666.67 533.33 19333.33 266.67 8.11 373.33 8.07 6.90 87.00 /dev/sda3 0.00 833.33 33.33 1700.00 266.67 22933.33 133.33 11466.67 13.38 6133.33 358.46 11.35 1966.67 在這個例子中,swap device(/dev/sda1) 和 file system device(/dev/sda3)在互相作用於I/O. 其中任一個會有很高寫請求(w/s),也會有很高wait time(await),或者較低的服務時間比率(svctm).這表明2個分區之間互有聯系,互有影響. 7.4 結論 I/O 性能監控包含了以下幾點: 1,當CPU 有等待I/O 情況時,那說明磁盤處於超負荷狀態. 2,計算你的磁盤能夠承受多大的IOPS 數. 3,確定你的應用是屬於隨機或者順序讀取磁盤. 4,監控磁盤慢需要比較wait time(await) 和 service time(svctm). 5,監控swap 和系統分區,要確保virtual memory不是文件系統I/O 的瓶頸.