磁盤IO滿負荷性能分析


磁盤IO滿負荷性能分析

有個項目最近發現在執行一些oracle數據庫的數據補入的sql語句時非常慢,經查發現來自存儲的硬盤io會沖到100busy

device  r/s   w/s           kr/s         kw/s    wait           actv        svc_t           %w            %b
sd2   18.2   1204.5    5480.8      9524.5    0.0            14.0        11.4          1             100

 
分析:
每秒有1K多次寫,即平均來講,每次寫的時間只有1ms,或者說每1ms就要完成1次寫操作分析硬盤
存儲硬盤:1W轉/分。平均尋道時間3.5ms,假設10個硬盤做raid5(不太確定)磁頭平均等待時間按磁頭每次都等待半圈計算,磁碟每轉半圈需要的時間=60秒/10000轉/2=3ms每個硬盤的平均尋址時間=3.5ms+3ms=6.5ms假設需求平攤到RAID5的硬盤上,按有效率提高7倍算,6.5ms/7<=1ms結論:應付每秒1千多次的隨機寫,存儲已經滿負荷了估計得從oracle上去想辦法,看能否優化查詢語句或合並一些隨機寫請求

同一台機器,另外一組不同時刻的數據

extended device statistics tty cpu
device r/s w/s kr/s kw/s wait actv svc_t %w %b
sd2 0.4 79.8 3.2 638.3 0.0 0.0 0.3 0 2
sd2 0.4 74.8 1.7 598.3 0.0 0.0 0.3 0 2
sd2 0.2 71.4 1.6 571.1 0.0 0.0 0.3 0 2
sd2 0.0 68.1 0.0 543.5 0.0 0.0 0.3 0 2
sd2 36.5 62.5 30700.1 500.0 0.0 0.7 7.2 0 43
sd2 74.9 48.8 65637.8 390.7 0.0 1.6 12.6 0 90 
sd2 45.2 87.6 42729.4 701.0 0.0 1.9 14.0 0 93 
sd2 76.6 74.4 73397.6 595.0 0.0 1.5 10.1 0 90 

這個就復雜了,讀寫才幾十MB字節,每秒讀寫次數都不到100,負荷居然也滿了…嘗試分析從第一行90busy的開始每秒種讀寫有 123.7次,消耗的總尋址時間為120+ms,即只有880ms不到的時間用於數據讀寫,完成了讀寫70MB左右。理論最高值讀寫合計可達到70MB/880ms×1000ms=80MB/S第二行 132.8,消耗132+ms,剩余870ms,完成50MB,50/870×1000=57MB/S
第三行 151.0,消耗150+ms,剩余850ms,完成80MB,80/850×1000=94MB/S暈了,存儲的磁盤RAID-5,從實際情況反推出來,最高理論值才接近100MB/S的水准??哦對了,和陣列連接的光纖卡速率也有關系,如果光纖卡是1gb,最高吞吐量200MBps,讀寫同時理論值最高可達100MBps,那差不多也就才到一半嘛怎么回事?如果是2gb的和4gb的,這么低的速率明顯就不對了。
$iostat -x 1  Linux 2.6.33-fukai (fukai-laptop)          _i686_    (2 CPU)  avg-cpu:  %user   %nice %system %iowait  %steal   %idle
 5.47    0.50    8.96   48.26    0.00   36.82
Device:  rrqm/s  wrqm/s   r/s    w/s  rsec/s  wsec/s avgrq-sz avgqu-sz  await  svctm  %util
sda    6.00   273.00   99.00    7.00  2240.00  2240.00    42.26     1.12   10.57   7.96  84.40
sdb    0.00     4.00    0.00  350.00     0.00  2068.00     5.91     0.55    1.58   0.54  18.80

rrqm/s:   每秒進行 merge 的讀操作數目。即 delta(rmerge)/s
wrqm/s:  每秒進行 merge 的寫操作數目。即 delta(wmerge)/s
r/s:           每秒完成的讀 I/O 設備次數。即 delta(rio)/s
w/s:         每秒完成的寫 I/O 設備次數。即 delta(wio)/s

rsec/s:    每秒讀扇區數。即 delta(rsect)/s
wsec/s:  每秒寫扇區數。即 delta(wsect)/s

rkB/s:      每秒讀K字節數。是 rsect/s 的一半,因為每扇區大小為512字節。(需要計算)
wkB/s:    每秒寫K字節數。是 wsect/s 的一半。(需要計算)

avgrq-sz: 平均每次設備I/O操作的數據大小 (扇區)。delta(rsect+wsect)/delta(rio+wio)
avgqu-sz: 平均I/O隊列長度。即 delta(aveq)/s/1000 (因為aveq的單位為毫秒)。

await:    平均每次設備I/O操作的等待時間 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio)
svctm:   平均每次設備I/O操作的服務時間 (毫秒)。即 delta(use)/delta(rio+wio)

%util:      一秒中有百分之多少的時間用於 I/O 操作,或者說一秒中有多少時間 I/O 隊列是非空的。即 delta(use)/s/1000 (因為use的單位為毫秒)

如果 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁盤
可能存在瓶頸。
idle小於70% IO壓力就較大了,一般讀取速度有較多的wait.

同時可以結合vmstat 查看查看b參數(等待資源的進程數)和wa參數(IO等待所占用的CPU時間的百分比,高過30%時IO壓力高)
另外 await 的參數也要多和 svctm 來參考。差的過高就一定有 IO 的問題。
avgqu-sz 也是個做 IO 調優時需要注意的地方,這個就是直接每次操作的數據的大小,如果次數多,但數據拿的小的話,其實 IO 也會很小.如果數據拿的大,才IO 的數據會高。也可以通過 avgqu-sz × ( r/s or w/s ) = rsec/s or wsec/s.也就是講,讀定速度是這個來決定的。

下面是別人寫的這個參數輸出的分析

# iostat -x 1
avg-cpu: %user %nice %sys %idle  16.24 0.00 4.31 79.44
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/cciss/c0d0  0.00 44.90 1.02 27.55 8.16 579.59   4.08 289.80 20.57    22.35    78.21 5.00 14.29

上面的 iostat 輸出表明秒有 28.57 次設備 I/O 操作: 總IO(io)/s = r/s(讀) +w/s(寫) = 1.02+27.55 = 28.57 (次/秒) 其中寫操作占了主體 (w:r = 27:1)。

平均每次設備 I/O 操作只需要 5ms 就可以完成,但每個 I/O 請求卻需要等上 78ms,為什么? 因為發出的 I/O 請求太多 (每秒鍾約 29 個),假設這些請求是同時發出的,那么平均等待時間可以這樣計算:

平均等待時間 = 單個 I/O 服務時間 * ( 1 + 2 + … + 請求總數-1) / 請求總數

應用到上面的例子: 平均等待時間 = 5ms * (1+2+…+28)/29 = 70ms,和 iostat 給出的78ms 的平均等待時間很接近。這反過來表明 I/O 是同時發起的。

每秒發出的 I/O 請求很多 (約 29 個),平均隊列卻不長 (只有 2 個 左右),這表明這 29 個請求的到來並不均勻,大部分時間 I/O 是空閑的。

一秒中有 14.29% 的時間 I/O 隊列中是有請求的,也就是說,85.71% 的時間里 I/O 系統無事可做,所有 29 個 I/O 請求都在142毫秒之內處理掉了。

delta(ruse+wuse)/delta(io) = await = 78.21 => delta(ruse+wuse)/s =78.21 * delta(io)/s = 78.21*28.57 = 2232.8,表明每秒內的I/O請求總共需要等待2232.8ms。所以平均隊列長度應為 2232.8ms/1000ms = 2.23,而 iostat 給出的平均隊列長度 (avgqu-sz) 卻為 22.35,為什么?! 因為 iostat 中有 bug,avgqu-sz 值應為 2.23,而不是 22.35。

IO系統性能之三:在Linux中監視IO性能

dd命令

dd其實是工作於比較低層的一個數據拷貝和轉換的*nix平台的工具,但是因為dd命令支持*nix平台的一些特殊設備,因此我們可以利用dd命令的這個特性來簡單的測試磁盤的性能。

先說一下兩個相關的特殊設備

/dev/null
空設備,通常用作輸出設備,這個是*nix系統上面的黑洞,所有送到這個空設備上的內容都會憑空消失。
/dev/zero
空字符,通常用作輸入,從/dev/zero中讀取時,它能源源不斷的提供空字符(ASCII NUL, 0×00)出來,要多少有多少。

於是就有了下面的用法:

  • 測試磁盤的寫入
/usr/bin/time dd if=/dev/zero of=/tmp/foo bs=4k count=1024000

這個命令時往磁盤的文件/tmp/foo中寫入一個4G大小的文件,當然文件的內容全部是空字符了,同時用/usr/bin/time來對命令的執行進行計時,命令中的bs指的是寫入文件時的塊大小,其實就相當於Oracle中的block大小了,count是寫入的塊數。采取這種方法來寫入數據時只是測試的連續讀磁盤的性能,而不是隨機讀的性能,不能采取這種方法檢查一個機器的IOPS的,只能檢查磁盤的吞吐率。

  • 測試磁盤的讀取
/usr/bin/time dd if=/tmp/foo of=/dev/null bs=4k

上面的命令是從/tmp/foo文件中讀取數據,然后扔掉,這里bs用的是讀取時塊的大小。和上面寫入的命令一樣,這樣測試的僅僅是最大的讀取性能,而不是隨機IO的性能。

  • 還能讀寫同時測試
/usr/bin/time dd if=/tmp/foo of=/tmp/foo2 bs=4k

在上面的命令中都用到了time命令對操作進行計時,這樣才能正確的進行判斷。要記住的一點是dd命令只能夠提供一個大概的測試,通過這個簡單的命令可以對磁盤系統的最大性能有一個大概的了解,要了解更詳細的信息還要通過其他方法來查看。


topiostat命令


top理解iostat的各項輸出

在Linux中,我們執行一個iostat -x命令,我們能看到如下的輸出

$iostat -x
Linux 2.4.21-50a6smp (linux)         11/03/2009

avg-cpu:  %user   %nice    %sys %iowait   %idle
0.42    0.00    0.26    0.47   98.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
hdc          0.01   0.00  0.00  0.00    0.07    0.00     0.03     0.00    24.48     0.00    4.90   4.57   0.00
hda          0.89   8.54  0.74  4.49   12.60  104.22     6.30    52.11    22.32     0.03    5.41   1.01   0.53

我們先列舉一下各個性能指標的簡單說明。

rrqm/s
每秒進行merge的讀操作數目。
wrqm/s
每秒進行merge的寫操作數目。
r/s
每秒完成的讀I/O設備次數。
w/s
每秒完成的寫I/O設備次數。
rsec/s
每秒讀扇區數。
wsec/s
每秒寫扇區數。
rkB/s
每秒讀K字節數。
wkB/s
每秒寫K字節數。
avgrq-sz
平均每次設備I/O操作的數據大小(扇區)。
avgqu-sz
平均I/O隊列長度。
await
平均每次設備I/O操作的等待時間(毫秒)。
svctm
平均每次設備I/O操作的服務時間(毫秒)。
%util
一秒中有百分之多少的時間用於I/O操作,或者說一秒中有多少時間I/O隊列是非空的。

要理解這些性能指標我們先看下圖

 

IO的執行過程的各個參數
IO的執行過程的各個參數

 

上圖的左邊是iostat顯示的各個性能指標,每個性能指標都會顯示在一條虛線之上,這表明這個性能指標是從虛線之上的那個讀寫階段開始計量的,比如說圖中的w/s從Linux IO scheduler開始穿過硬盤控制器(CCIS/3ware),這就表明w/s統計的是每秒鍾從Linux IO scheduler通過硬盤控制器的寫IO的數量。

結合上圖對讀IO操作的過程做一個說明,在從OS Buffer Cache傳入到OS Kernel(Linux IO scheduler)的讀IO操作的個數實際上是rrqm/s+r/s,直到讀IO請求到達OS Kernel層之后,有每秒鍾有rrqm/s個讀IO操作被合並,最終轉送給磁盤控制器的每秒鍾讀IO的個數為r/w;在進入到操作系統的設備層(/dev/sda)之后,計數器開始對IO操作進行計時,最終的計算結果表現是await,這個值就是我們要的IO響應時間了;svctm是在IO操作進入到磁盤控制器之后直到磁盤控制器返回結果所花費的時間,這是一個實際IO操作所花的時間,當await與svctm相差很大的時候,我們就要注意磁盤的IO性能了;而avgrq-sz是從OS Kernel往下傳遞請求時單個IO的大小,avgqu-sz則是在OS Kernel中IO請求隊列的平均大小。

現在我們可以將iostat輸出結果和我們前面討論的指標掛鈎了。

平均單次IO大小(IO Chunk Size) <=> avgrq-sz

平均IO響應時間(IO Response Time) <=> await

IOPS(IO per Second) <=> r/s + w/s

吞吐率(Throughtput) <=> rkB/s + wkB/s


topiostat的應用實例

top觀察IO Scheduler的IO合並(IO Merge)

前面說過IO在執行過程中會被合並以提高效率,下面就結合dd命令和iostat命令看一下。

我們先執行dd命令,設置bs參數值為1k,完整命令如下

dd if=/dev/zero of=test bs=1k count=1024000

同時打開另外一個終端執行iostat命令,這里只查看變化那個磁盤的更改,每秒刷新一次數據,完整命令如下

iostat -x hdc7 1

然后我們可以得到下面的結果

Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
hdc7         0.00 9447.00  0.00 776.00    0.00 80616.00     0.00 40308.00   103.89   480.18  805.95   1.29 100.00

avg-cpu:  %user   %nice    %sys %iowait   %idle
0.50    0.00   56.00   43.50    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
hdc7         0.00 9534.00  0.00 872.00    0.00 81384.00     0.00 40692.00    93.33   274.56  401.19   1.14  99.00

avg-cpu:  %user   %nice    %sys %iowait   %idle
2.50    0.00   46.50   14.00   37.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
hdc7         0.00 6766.00  1.00 276.00    8.00 58808.00     4.00 29404.00   212.33   197.27  321.66   1.95  54.00

avg-cpu:  %user   %nice    %sys %iowait   %idle
0.50    0.00    0.50    0.00   99.00

看結果中第一組數據中的avgrq-sz,為103.89個扇區,磁盤的每個扇區為512字節,因此平均IO大小為103.89*512/1024=52k字節,遠遠大於我們dd命令時給定的參數1k字節,也就是說IO在中間被合並了。看巨大的wrqm/s也能得出同樣的結論。

 


top附:在Windows中監視IO性能

本來准備寫一篇windows中監視IO性能的,后來發現好像可寫的內容不多,windows在細節這方面做的不是那么的好,不過那些基本信息還是有的。

在Windows中監視性能基本都用性能監視器了,與IO性能相關的有兩個大類,一個是”LogicalDisk”,另外一個是”PhysicalDisk”,”LogicalDisk”更多的是用來監視文件相關的IO性能,而”PhysicalDisk”則是用來監視LUN或者是磁盤卷,下面就列舉下與前面所列舉的IO性能相關的計數器,具體的自己研究了:

單次IO大小
  • Avg. Disk Bytes/Read
  • Avg. Disk Bytes/Write
IO響應時間
  • Avg. Disk sec/Read
  • Avg. Disk sec/Write
IOPS
  • Disk Reads/sec
  • Disk Writes/sec
  • Disk Transfers/sec
IO吞吐率
  • Disk Bytes/sec
  • Disk Read Bytes/sec
  • Disk Write Bytes/sec
 
 
 
 

IOPS (Input/Output Per Second)即每秒的輸入輸出量(或讀寫次數),是衡量磁盤性能的主要指標之一。IOPS是指單位時間內系統能處理的I/O請求數量,一般以每秒處理的I/O請求數量為單位,I/O請求通常為讀或寫數據操作請求。隨機讀寫頻繁的應用,如OLTP(Online Transaction Processing),IOPS是關鍵衡量指標。另一個重要指標是數據吞吐量(Throughput),指單位時間內可以成功傳輸的數據數量。對於大量順序讀寫的應用,如VOD(Video On Demand),則更關注吞吐量指標。

傳統磁盤本質上一種機械裝置,如FC, SAS, SATA磁盤,轉速通常為5400/7200/10K/15K rpm不等。影響磁盤的關鍵因素是磁盤服務時間,即磁盤完成一個I/O請求所花費的時間,它由尋道時間、旋轉延遲和數據傳輸時間三部分構成。
尋道時間Tseek是指將讀寫磁頭移動至正確的磁道上所需要的時間。尋道時間越短,I/O操作越快,目前磁盤的平均尋道時間一般在3-15ms。
旋轉延遲Trotation是指盤片旋轉將請求數據所在扇區移至讀寫磁頭下方所需要的時間。旋轉延遲取決於磁盤轉速,通常使用磁盤旋轉一周所需時間的1/2表示。比如,7200 rpm的磁盤平均旋轉延遲大約為60*1000/7200/2 = 4.17ms,而轉速為15000 rpm的磁盤其平均旋轉延遲約為2ms。
數據傳輸時間Ttransfer是指完成傳輸所請求的數據所需要的時間,它取決於數據傳輸率,其值等於數據大小除以數據傳輸率。目前IDE/ATA能達到133MB/s,SATA II可達到300MB/s的接口數據傳輸率,數據傳輸時間通常遠小於前兩部分時間。

因此,理論上可以計算出磁盤的最大IOPS,即IOPS = 1000 ms/ (Tseek + Troatation),忽略數據傳輸時間。假設磁盤平均物理尋道時間為3ms, 磁盤轉速為7200,10K,15K rpm,則磁盤IOPS理論最大值分別為,
IOPS = 1000 / (3 + 60000/7200/2) = 140
IOPS = 1000 / (3 + 60000/10000/2) = 167
IOPS = 1000 / (3 + 60000/15000/2) = 200
固態硬盤SSD是一種電子裝置, 避免了傳統磁盤在尋道和旋轉上的時間花費,存儲單元尋址開銷大大降低,因此IOPS可以非常高,能夠達到數萬甚至數十萬。實際測量中,IOPS數值會受到很多因素的影響,包括I/O負載特征(讀寫比例,順序和隨機,工作線程數,隊列深度,數據記錄大小)、系統配置、操作系統、磁盤驅動等等。因此對比測量磁盤IOPS時,必須在同樣的測試基准下進行,即便如何也會產生一定的隨機不確定性。通常情況下,IOPS可細分為如下幾個指標:
Toatal IOPS,混合讀寫和順序隨機I/O負載情況下的磁盤IOPS,這個與實際I/O情況最為相符,大多數應用關注此指標。
Random Read IOPS,100%隨機讀負載情況下的IOPS。
Random Write IOPS,100%隨機寫負載情況下的IOPS。
Sequential Read IOPS,100%順序負載讀情況下的IOPS。
Sequential Write IOPS,100%順序寫負載情況下的IOPS。

IOPS的測試benchmark工具主要有IometerIoZoneFIO等,可以綜合用於測試磁盤在不同情形下的IOPS。對於應用系統,需要首先確定數據的負載特征,然后選擇合理的IOPS指標進行測量和對比分析,據此選擇合適的存儲介質和軟件系統。下面的磁盤IOPS數據來自http://en.wikipedia.org/wiki/IOPS,給大家一個基本參考。

 

 

 

 

È

Device IOPS Interface Notes
7200 RPM SATAdrives ~90 IOPS SATA II  
10k RPM SATAdrives, queue depth 1 ~130 IOPS SATA II fio -readonly -name iops -rw=randread -bs=512 -runtime=20 -iodepth 1 -filename /dev/sda -ioengine libaio -direct=1
10k RPM Serial Attached SCSIdrives ~140 IOPS SAS  
15k RPM Serial Attached SCSIdrives ~180 IOPS SAS  
10k RPM SATAdrives, queue depth 24 ~290 IOPS SATA II fio -readonly -name iops -rw=randread -bs=512 -runtime=20 -iodepth 24 -filename /dev/sda -ioengine libaio -direct=1
Simple SLC SSD ~400 IOPS SATA II  
Intel X25-M G2 (MLC; As of March 2010) ~8,600 IOPS SATA II Intel’s data sheet claims 6,600/8,600 IOPS (80GB/160GB version) and 35,000 IOPS for random 4KB writes and reads, respectively.
Intel X25-E (SLC; As of March 2009) ~5,000 IOPS SATA II Intel’s data sheet claims 3,300 IOPS and 35,000 IOPS for writes and reads, respectively. 5,000 IOPS are measured for a mix. Intel X25-E G1 has around 3 times higher IOPS compared to the Intel X25-M G2.
OCZ Z-Drive e84, a PCI Express SLC Solid State Drive 16,000 IOPS PCIe Maximum read/write speed of 800/750 MB/s).
G.Skill Phoenix Pro et. al. ~20,000 IOPS SATA III SandForce-1200 based SSD drives with enhanced firmware, states up to 50,000 IOPS, but real-world performance shows for all drives from different manufacturers ~25,000 IOPS for random read and ~15,000 IOPS for random write.
ioDrive, a PCI-Express card with Flash 140,000 Read IOPS, 135,000 Write IOPS PCIe  
ioDrive Duo 250,000+ IOPS PCIe  
DDRdrive X1, a May 2009 PCI Express based solid-state drive 300,000+ (512B Random Read IOPS) and 200,000+ (512B Random Write IOPS) PCIe  
Texas Memory SystemRamSan-20 120,000+ Random Read/Write IOPS PCIe Inlude RAM cache and UltraCapacitor to preserve the memory non-volatile
Texas Memory SystemRamSan-630 Appliance 1,000,000+ Random Read/Write IOPS FC / InfiniBand  
Violin Memory Appliance 1,000,000+ Random Read/Write IOPS Proprietary interconnect  
ioDrive Octal (single PCI Express card) 1,000,000+ Random Read/Write IOPS PCIe


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM