Linux性能監(jiān)測:磁盤IO篇
磁盤通常是計算機最慢的子系統(tǒng),也是最容易出現(xiàn)性能瓶頸的地方,因為磁盤離 CPU 距離最遠而且 CPU 訪問磁盤要涉及到機械操作,比如轉(zhuǎn)軸、尋軌等。訪問硬盤和訪問內(nèi)存之間的速度差別是以數(shù)量級來計算的,就像1天和1分鐘的差別一樣。要監(jiān)測 IO 性能,有必要了解一下基本原理和 Linux 是如何處理硬盤和內(nèi)存之間的 IO 的。
內(nèi)存頁
上一篇 Linux 性能監(jiān)測:Memory 提到了內(nèi)存和硬盤之間的 IO 是以頁為單位來進行的,在 Linux 系統(tǒng)上1頁的大小為 4K。可以用以下命令查看系統(tǒng)默認的頁面大?。?/p>
$ /usr/bin/time -v date ... Page size (bytes): 4096 ...
缺頁中斷
Linux 利用虛擬內(nèi)存極大的擴展了程序地址空間,使得原來物理內(nèi)存不能容下的程序也可以通過內(nèi)存和硬盤之間的不斷交換(把暫時不用的內(nèi)存頁交換到硬盤,把需要的內(nèi)存頁從硬盤讀到內(nèi)存)來贏得更多的內(nèi)存,看起來就像物理內(nèi)存被擴大了一樣。事實上這個過程對程序是完全透明的,程序完全不用理會自己哪一部分、什么時候被交換進內(nèi)存,一切都有內(nèi)核的虛擬內(nèi)存管理來完成。當程序啟動的時候,Linux 內(nèi)核首先檢查 CPU 的緩存和物理內(nèi)存,如果數(shù)據(jù)已經(jīng)在內(nèi)存里就忽略,如果數(shù)據(jù)不在內(nèi)存里就引起一個缺頁中斷(Page Fault),然后從硬盤讀取缺頁,并把缺頁緩存到物理內(nèi)存里。缺頁中斷可分為主缺頁中斷(Major Page Fault)和次缺頁中斷(Minor Page Fault),要從磁盤讀取數(shù)據(jù)而產(chǎn)生的中斷是主缺頁中斷;數(shù)據(jù)已經(jīng)被讀入內(nèi)存并被緩存起來,從內(nèi)存緩存區(qū)中而不是直接從硬盤中讀取數(shù)據(jù)而產(chǎn)生的中斷是次缺頁中斷。
上面的內(nèi)存緩存區(qū)起到了預(yù)讀硬盤的作用,內(nèi)核先在物理內(nèi)存里尋找缺頁,沒有的話產(chǎn)生次缺頁中斷從內(nèi)存緩存里找,如果還沒有發(fā)現(xiàn)的話就從硬盤讀取。很顯然,把多余的內(nèi)存拿出來做成內(nèi)存緩存區(qū)提高了訪問速度,這里還有一個命中率的問題,運氣好的話如果每次缺頁都能從內(nèi)存緩存區(qū)讀取的話將會極大提高性能。要提高命中率的一個簡單方法就是增大內(nèi)存緩存區(qū)面積,緩存區(qū)越大預(yù)存的頁面就越多,命中率也會越高。下面的 time 命令可以用來查看某程序第一次啟動的時候產(chǎn)生了多少主缺頁中斷和次缺頁中斷:
$ /usr/bin/time -v date ... Major (requiring I/O) page faults: 1 Minor (reclaiming a frame) page faults: 260 ...
File Buffer Cache
從上面的內(nèi)存緩存區(qū)(也叫文件緩存區(qū) File Buffer Cache)讀取頁比從硬盤讀取頁要快得多,所以 Linux 內(nèi)核希望能盡可能產(chǎn)生次缺頁中斷(從文件緩存區(qū)讀),并且能盡可能避免主缺頁中斷(從硬盤讀),這樣隨著次缺頁中斷的增多,文件緩存區(qū)也逐步增大,直到系統(tǒng)只有少量可用物理內(nèi)存的時候 Linux 才開始釋放一些不用的頁。我們運行 Linux 一段時間后會發(fā)現(xiàn)雖然系統(tǒng)上運行的程序不多,但是可用內(nèi)存總是很少,這樣給大家造成了 Linux 對內(nèi)存管理很低效的假象,事實上 Linux 把那些暫時不用的物理內(nèi)存高效的利用起來做預(yù)存(內(nèi)存緩存區(qū))呢。下面打印的是 VPSee 的一臺 Sun 服務(wù)器上的物理內(nèi)存和文件緩存區(qū)的情況:
$ cat /proc/meminfo MemTotal: 8182776 kB MemFree: 3053808 kB Buffers: 342704 kB Cached: 3972748 kB
這臺服務(wù)器總共有 8GB 物理內(nèi)存(MemTotal),3GB 左右可用內(nèi)存(MemFree),343MB 左右用來做磁盤緩存(Buffers),4GB 左右用來做文件緩存區(qū)(Cached),可見 Linux 真的用了很多物理內(nèi)存做 Cache,而且這個緩存區(qū)還可以不斷增長。
頁面類型
Linux 中內(nèi)存頁面有三種類型:
- Read pages,只讀頁(或代碼頁),那些通過主缺頁中斷從硬盤讀取的頁面,包括不能修改的靜態(tài)文件、可執(zhí)行文件、庫文件等。當內(nèi)核需要它們的時候把它們讀到內(nèi)存中,當內(nèi)存不足的時候,內(nèi)核就釋放它們到空閑列表,當程序再次需要它們的時候需要通過缺頁中斷再次讀到內(nèi)存。
 - Dirty pages,臟頁,指那些在內(nèi)存中被修改過的數(shù)據(jù)頁,比如文本文件等。這些文件由 pdflush 負責同步到硬盤,內(nèi)存不足的時候由 kswapd 和 pdflush 把數(shù)據(jù)寫回硬盤并釋放內(nèi)存。
 - Anonymous pages,匿名頁,那些屬于某個進程但是又和任何文件無關(guān)聯(lián),不能被同步到硬盤上,內(nèi)存不足的時候由 kswapd 負責將它們寫到交換分區(qū)并釋放內(nèi)存。
 
IO’s Per Second(IOPS)
每次磁盤 IO 請求都需要一定的時間,和訪問內(nèi)存比起來這個等待時間簡直難以忍受。在一臺 2001 年的典型 1GHz PC 上,磁盤隨機訪問一個 word 需要 8,000,000 nanosec = 8 millisec,順序訪問一個 word 需要 200 nanosec;而從內(nèi)存訪問一個 word 只需要 10 nanosec.(數(shù)據(jù)來自:Teach Yourself Programming in Ten Years)這個硬盤可以提供 125 次 IOPS(1000 ms / 8 ms)。
順序 IO 和 隨機 IO
IO 可分為順序 IO 和 隨機 IO 兩種,性能監(jiān)測前需要弄清楚系統(tǒng)偏向順序 IO 的應(yīng)用還是隨機 IO 應(yīng)用。順序 IO 是指同時順序請求大量數(shù)據(jù),比如數(shù)據(jù)庫執(zhí)行大量的查詢、流媒體服務(wù)等,順序 IO 可以同時很快的移動大量數(shù)據(jù)??梢赃@樣來評估 IOPS 的性能,用每秒讀寫 IO 字節(jié)數(shù)除以每秒讀寫 IOPS 數(shù),rkB/s 除以 r/s,wkB/s 除以 w/s. 下面顯示的是連續(xù)2秒的 IO 情況,可見每次 IO 寫的數(shù)據(jù)是增加的(45060.00 / 99.00 = 455.15 KB per IO,54272.00 / 112.00 = 484.57 KB per IO)。相對隨機 IO 而言,順序 IO 更應(yīng)該重視每次 IO 的吞吐能力(KB per IO):
$ iostat -kx 1
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    2.50   25.25    0.00   72.25
Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdb       24.00 19995.00 29.00 99.00  4228.00 45060.00   770.12    45.01  539.65   7.80  99.80
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    1.00   30.67    0.00   68.33
Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdb        3.00 12235.00  3.00 112.00   768.00 54272.00   957.22   144.85  576.44   8.70 100.10
隨機 IO 是指隨機請求數(shù)據(jù),其 IO 速度不依賴于數(shù)據(jù)的大小和排列,依賴于磁盤的每秒能 IO 的次數(shù),比如 Web 服務(wù)、Mail 服務(wù)等每次請求的數(shù)據(jù)都很小,隨機 IO 每秒同時會有更多的請求數(shù)產(chǎn)生,所以磁盤的每秒能 IO 多少次是關(guān)鍵。
$ iostat -kx 1
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.75    0.00    0.75    0.25    0.00   97.26
Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdb        0.00    52.00  0.00 57.00     0.00   436.00    15.30     0.03    0.54   0.23   1.30
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.75    0.00    0.75    0.25    0.00   97.24
Device:  rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sdb        0.00    56.44  0.00 66.34     0.00   491.09    14.81     0.04    0.54   0.19   1.29
按照上面的公式得出:436.00 / 57.00 = 7.65 KB per IO,491.09 / 66.34 = 7.40 KB per IO. 與順序 IO 比較發(fā)現(xiàn),隨機 IO 的 KB per IO 小到可以忽略不計,可見對于隨機 IO 而言重要的是每秒能 IOPS 的次數(shù),而不是每次 IO 的吞吐能力(KB per IO)。
SWAP
當系統(tǒng)沒有足夠物理內(nèi)存來應(yīng)付所有請求的時候就會用到 swap 設(shè)備,swap 設(shè)備可以是一個文件,也可以是一個磁盤分區(qū)。不過要小心的是,使用 swap 的代價非常大。如果系統(tǒng)沒有物理內(nèi)存可用,就會頻繁 swapping,如果 swap 設(shè)備和程序正要訪問的數(shù)據(jù)在同一個文件系統(tǒng)上,那會碰到嚴重的 IO 問題,最終導(dǎo)致整個系統(tǒng)遲緩,甚至崩潰。swap 設(shè)備和內(nèi)存之間的 swapping 狀況是判斷 Linux 系統(tǒng)性能的重要參考,我們已經(jīng)有很多工具可以用來監(jiān)測 swap 和 swapping 情況,比如:top、cat /proc/meminfo、vmstat 等:
$ cat /proc/meminfo MemTotal: 8182776 kB MemFree: 2125476 kB Buffers: 347952 kB Cached: 4892024 kB SwapCached: 112 kB ... SwapTotal: 4096564 kB SwapFree: 4096424 kB ... $ vmstat 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r b swpd free buff cache si so bi bo in cs us sy id wa st 1 2 260008 2188 144 6824 11824 2584 12664 2584 1347 1174 14 0 0 86 0 2 1 262140 2964 128 5852 24912 17304 24952 17304 4737 2341 86 10 0 0 4
原文鏈接:http://www.vpsee.com/2009/11/linux-system-performance-monitoring-io/















 
 
 


 
 
 
 