關(guān)于磁盤I/O測試工具Bonnie++的專題
作者簡介:
張樂奕,通常使用的網(wǎng)名為kamus,也曾用過seraphim,現(xiàn)在任職于北京某大型軟件公司,Oracle數(shù)據(jù)庫DBA,主要負(fù)責(zé)證券行業(yè)的核心交易系統(tǒng)數(shù)據(jù)庫管理及維護(hù)工作。
熱切關(guān)注Oracle技術(shù)和相關(guān)操作系統(tǒng)技術(shù),出沒于各大數(shù)據(jù)庫技術(shù)論壇,目前是中國最大的Oracle技術(shù)論壇www.itpub.net的數(shù)據(jù)庫管理版版主。
閱讀更多技術(shù)文章和隨筆可以登錄我的個(gè)人blog,http://blog.cdsn.net/kamus
目錄
前言
安裝
使用.
評測.
相關(guān)鏈接
前言
最早是eygle在itpub上推薦這個(gè)工具,起因是我對于Sun的軟RAID性能提出的置疑,后來eygle陸續(xù)用這個(gè)工具作了一些盤陣IO的測試,包括EMC和T3的一些比較。
這些測試結(jié)果都發(fā)表在eygle的個(gè)人站點(diǎn)上,見本文最后相關(guān)鏈接部分。
但是我卻一直沒有自己用Bonnie++測試過IO性能,最近一個(gè)客戶要修改自己盤陣的RAID配置,本來就是使用D2的陣列,只能支持軟RAID的一個(gè)性能比較差的古老東東了,在我們的測試過程中忽然又發(fā)現(xiàn)12塊盤的盤陣配置的是RAID10,但是同時(shí)只有2塊盤在作讀寫,也就是stripe設(shè)置只是2,這個(gè)問題在一年多以前剛上系統(tǒng)的時(shí)候就是這樣,居然一直沒有發(fā)現(xiàn)用了這么長時(shí)間。
客戶最終決定重新設(shè)置一下RAID的配置,首先將redo和datafile分開,redo所在的盤用4塊作RAID10,剩下8塊再作RAID10,供數(shù)據(jù)文件使用,并且重新設(shè)置stripe,redo所在的lun設(shè)置為2,datafile所在的lun設(shè)置為4。
從理論上看,這樣的修改應(yīng)該會大幅度提到整個(gè)數(shù)據(jù)庫的I/O效率,但是客戶要求能夠有一個(gè)實(shí)際的修改效果報(bào)告,也就是需要作修改前和修改后的對比。
這樣,于是決定使用bonnie++來作磁盤級的修改效果報(bào)告。至于數(shù)據(jù)庫級的修改效果自然有壓力測試程序可以完成,此處不表。
既然決定使用,那么自然要琢磨一下該怎么用了。剛剛bonnie++已經(jīng)開始運(yùn)行了,于是閑下來,寫了這篇文章。
安裝
其實(shí)今天大部分的時(shí)間是耗在怎么讓bonnie++運(yùn)行起來上面了。
從bonnie++的主頁上下載了最新的source,bonnie++1.03a.tgz。
gunzip bonnie++-1.03a.tgz
生成bonnie++-1.03a.tar文件,然后解包
tar xvf bonnie++-1.03a.tar
生成bonnie++-1.03a文件夾
cd bonnie++-1.03a
make
報(bào)錯。
/usr/ucb/cc: language optional software package not installed
原來編譯器就根本沒裝。
先介紹一下主機(jī)情況,一臺SunFire v480,兩塊73G內(nèi)置硬盤,4個(gè)UltraSPARC-III+的CPU,8G內(nèi)存,安裝的是Solaris8,由于需要模擬真實(shí)環(huán)境,所以安裝的是比較老的02.2版本,而且沒有打任何patch。
在Sun給的安裝光盤中居然沒有找到Companion CD,編譯器應(yīng)該是在這張盤上,沒辦法只好上網(wǎng)自己找,還好,很快就找到一個(gè)很棒的站點(diǎn)blastwave,包括了Solaris8,9的sparc和x86版本的所有需要的package。
根據(jù)gcc包下載頁面中的說明,發(fā)現(xiàn)需要下載下面四個(gè)package。
common-1.3.3-SunOS5.8-sparc-CSW.pkg.gz
gcc3rt-3.3.3,REV=2004.04.23-SunOS5.8-sparc-CSW.pkg.gz
libiconv-1.8,REV=2003.01.12-SunOS5.8-sparc-CSW.pkg.gz
gcc3-3.3.3,REV=2004.03.22-SunOS5.8-sparc-CSW.pkg.gz
前面三個(gè)包是最后gcc3包的前提條件,必須安裝。全部下載完畢,開始安裝第一個(gè)包,也就是common那個(gè)包,報(bào)錯。
提示操作系統(tǒng)的110934補(bǔ)丁版本過低,需要升級。
OK,再上網(wǎng)找,直接用google查,關(guān)鍵字是“110934 soalris”,通常前面幾個(gè)link就會指向SunSolve站點(diǎn)的下載頁面,patch通常不大,很快就下載完了。
開始打補(bǔ)丁,patchadd 110934-21。
系統(tǒng)運(yùn)行半天,報(bào)錯。
說要安裝這個(gè)補(bǔ)丁就需要先安裝110380-04的補(bǔ)丁。我倒。
再上網(wǎng)找,下載完110380-04,先patchadd 110380-04,一切正常。
再重新patchadd 110934-21,一切正常。
打完補(bǔ)丁以后,重新安裝common包,OK,一切正常。
pkgadd -d common-1.3.3-SunOS5.8-sparc-CSW.pkg.gz
然后依次安裝其它的包,一切正常。
這個(gè)包將gcc安裝到/opt/csw/gcc3目錄下。
說明文件指出安裝完gcc將創(chuàng)建/opt/csw/bin下的gcc執(zhí)行程序,所以要求將這個(gè)路徑加入用戶的PATH變量中,但是實(shí)際上安裝完gcc3.3的版本以后,并沒有在上面的路徑中生成任何文件。
后來我再安裝gcc2.95版本的時(shí)候發(fā)現(xiàn)這個(gè)版本的安裝才是將gcc生成到/opt/csw/bin中。
所以如果我們在Solaris8中即安裝了gcc2.95又安裝了gcc3.3,那么要注意這兩個(gè)版本的gcc文件在不同的路徑下,其實(shí)這也是應(yīng)該的,否則新版本會覆蓋舊版本,往往是很多人不愿意的。
回到上面,安裝完gcc3以后,再次運(yùn)行make,仍然報(bào)錯。
/usr/ucb/cc: language optional software package not installed
檢查PATH環(huán)境變量,已經(jīng)將/opt/csw/gcc3/bin目錄加入了。
想了一下,感覺應(yīng)該是系統(tǒng)還在使用原來的/usr/ucb/cc。于是將cc鏈接到新安裝的gcc上,這樣無論什么時(shí)候調(diào)用cc其實(shí)都是直接使用gcc了。
whereis cc
cd /usr/ucb
mv cc cc.org
ln -s /opt/csw/gcc3/bin/gcc /usr/ucb/cc
備注:如果要安裝gcc2的包,那么需要下載下面兩個(gè)package。
gcc2rt-2.95.3,REV=2003.03.01-SunOS5.8-sparc-CSW.pkg.gz
gcc2-2.95.3-SunOS5.8-sparc-CSW.pkg.gz
安裝完畢以后,同樣是將cc鏈接到這個(gè)版本的gcc上。
whereis cc
cd /usr/ucb
mv cc cc.org
ln -s /opt/csw/bin/gcc /usr/ucb/cc
修改完畢以后編譯成功。
運(yùn)行bonnie++,報(bào)錯。
libstdc++.so.5: cannot open shared object file: No such file or directory.
繼續(xù)查資料,發(fā)現(xiàn)bonnie++尋找的lib路徑是環(huán)境變量LD_LIBRARY_PATH指定的路徑,但是這個(gè)路徑下并沒有libstdc++.so.5文件,于是手工將libstdc++.so.5文件從gcc3的安裝路徑中ln到/usr/lib下面。
# ln -s /opt/csw/gcc3/lib/libstdc++.so.5 /usr/lib/libstdc++.so.5
再次運(yùn)行,仍然報(bào)錯。
libgcc_s.so.1: cannot open shared object file: No such file or directory.
這次就輕車熟路了,直接再作一次link。
# ln -s /opt/csw/gcc3/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1
終于,bonnie++可以正常運(yùn)行了。
我們可以不需要自己編譯,在eygle的站點(diǎn)上有Solaris8下載編譯好的bonnie++。直接可以使用,當(dāng)然如果運(yùn)行報(bào)libstdc++.so.5找不到的問題,還需要按照上面的方法解決。
使用.
接下來繼續(xù)介紹bonnie++(Version: 1.03)的使用方法以及結(jié)果的含義。
usage: bonnie++ [-d scratch-dir] [-s size(Mb)[:chunk-size(b)]]
[-n number-to-stat[:max-size[:min-size][:num-directories]]]
[-m machine-name]
[-r ram-size-in-Mb]
[-x number-of-tests] [-u uid-to-use:gid-to-use] [-g gid-to-use]
[-q] [-f] [-b] [-p processes -y]
首先說明一下命令中常用的參數(shù)。
-d 生成測試文件的路徑
-s 生成測試文件的大小,以M為單位(如果不使用-r參數(shù),則要求文件大小至少是系統(tǒng)物理內(nèi)存的2倍)
-m 機(jī)器名,實(shí)際上我們可以認(rèn)為是本次測試的方案名,可以隨便定義。默認(rèn)是本機(jī)的hostname。
-r 內(nèi)存大小,指定內(nèi)存大小,這樣可以通過-s參數(shù)創(chuàng)建r*2大小的文件,通常用于縮短測試時(shí)間,但是需要注意這樣由于內(nèi)存的cache可能導(dǎo)致測試結(jié)果的不準(zhǔn)確
-x 測試的次數(shù)
-u 測試文件的屬主和組,默認(rèn)是執(zhí)行bonnie++的當(dāng)前用戶和當(dāng)前組
-g 測試文件的組,默認(rèn)是執(zhí)行bonnie++的當(dāng)前用組
-b 在每次寫文件時(shí)調(diào)用fsync()函數(shù),對于測試郵件服務(wù)器或者數(shù)據(jù)庫服務(wù)器這種通常需要同步操作的情況比較適合,而不使用該參數(shù)則比較適合測試copy文件或者編譯等操作的效率。
通常我們可以簡單地運(yùn)行如下命令進(jìn)行磁盤性能測試:
bonnie++ -d /global/oradata –m sun3510
這樣將會在指定的目錄下(通常我們會指定一個(gè)盤陣上卷的掛載點(diǎn)),生成相當(dāng)于主機(jī)物理內(nèi)存兩倍的文件,如果總量大于1G,則生成多個(gè)大小為1G的文件。假設(shè)主機(jī)內(nèi)存為4G,那么在測試中就會生成8個(gè)1G的文件,到測試結(jié)束,這些文件會被自動刪除。
如果我們的主機(jī)內(nèi)存是4G,但是我們想縮短測試的時(shí)間,比如說只寫2G的文件,就應(yīng)該執(zhí)行下面的命令:
bonnie++ -d /global/oradata –m sun3510 –s 2048 –r 1024
bonnie++的在測試的時(shí)候通常會占用大量的IO和CPU,所以請不要在生產(chǎn)環(huán)境的業(yè)務(wù)高峰期進(jìn)行測試。
下面看一個(gè)測試結(jié)果,通過這個(gè)結(jié)果我們解釋一下到底bonnie++在測試過程中都作了什么,而每一個(gè)輸出的結(jié)果又表示了什么。
這個(gè)測試結(jié)果是在一臺SunFire V880 + D2陣列上進(jìn)行的,主機(jī)配置是2個(gè)UltraSparc-III+ 900MHz的CPU,4G內(nèi)存,而D2陣列是滿配的12塊36G SCSI磁盤,劃分了兩個(gè)LUN,我們的測試目的地/global/oradata建立在其中的一個(gè)LUN上,使用了8塊磁盤,用Veritas Volum Manager作了RAID10,stripe(也就是ncol)設(shè)置為4。
bonnie++ -d /global/oradata -s 8192 -m d2new -u oracle
Using uid:1001, gid:101.
Writing with putc()...done
Writing intelligently...done
Rewriting...done
Reading with getc()...done
Reading intelligently...done
start 'em...done...done...done...
Create files in sequential order...done.
Stat files in sequential order...done.
Delete files in sequential order...done.
Create files in random order...done.
Stat files in random order...done.
Delete files in random order...done.
Version 1.03 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
d2new 8G 18275 62 32832 26 25423 55 27444 94 106842 60 549.9 7
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 1723 15 +++++ +++ 5059 40 4821 37 +++++ +++ 653 5
依次解讀一下,從Writing with putc()開始到Delete files in random order…結(jié)束,這是bonnie++作的12項(xiàng)測試,這12項(xiàng)測試依次對應(yīng)12項(xiàng)結(jié)果,而這12項(xiàng)結(jié)果又被分為了5大類,分別是Sequential Output(寫測試),Sequential Input(讀測試),Random Seeks(讀寫測試),Sequential Create(順序讀寫文件測試)和Random Create(隨意讀寫文件測試)。
那么測試步驟和測試結(jié)果依次對應(yīng)的順序就是:
Writing with putc() -> Sequential Output的Per Chr
Writing intelligently -> Sequential Output的Block
Rewriting -> Sequential Output的Rewrite
Reading with getc() -> Sequential Input的Per Chr
Reading intelligently -> Sequential Input的Block
start 'em -> Random Seeks
Create files in sequential order -> Sequential Create的Create
Stat files in sequential order -> Sequential Create的Read
Delete files in sequential order -> Sequential Create的Delete
Create files in random order -> Random Create的Create
Stat files in random order -> Random Create的Read
Delete files in random order -> Random Create的Delete
每個(gè)結(jié)果中又包括了2項(xiàng)數(shù)值,一個(gè)是K字節(jié)數(shù)或者文件數(shù),另一個(gè)是%CP,就是執(zhí)行這項(xiàng)測試時(shí)CPU的平均占用率。
對于輸出結(jié)果的評價(jià),我們認(rèn)為在相等CPU的占用率情況下,存取字節(jié)數(shù)越高表示該存儲設(shè)備的吞吐量越大,自然性能也就越好。
值得注意的是,在測試RAID的時(shí)候,對于多CPU的系統(tǒng),bonnie++并沒有發(fā)揮CPU的最大潛力,也就是說bonnie++發(fā)出的I/O請求通常不夠達(dá)到CPU和磁盤的最大壓力,這時(shí)候顯示的吞吐量就不是這個(gè)存儲設(shè)備能夠達(dá)到的最大值。我們可以在測試的同時(shí)通過iostat,mpstat,sar等命令監(jiān)控系統(tǒng)狀況,如果沒有明顯的I/O等待,通常表示測試軟件的壓力不夠。在bonnie++的主頁上也表示對于多CPU多進(jìn)程的支持將放到2.0版本中去實(shí)現(xiàn)。
明白了測試步驟和測試結(jié)果之后,我們再來進(jìn)一步看看每個(gè)測試結(jié)果都是什么含義。
Sequential Output
1. Per Char
就是Per-Character的含義。使用putc()函數(shù)進(jìn)行循環(huán)寫入,每次寫入的字節(jié)很小,基本上可以放入任意一種I-Cache中,這種情況下的CPU消耗在處理putc()代碼和分配磁盤文件空間上。
2. Block
使用write(2)函數(shù)創(chuàng)建文件。這種情況下的CPU消耗只是在分配磁盤文件空間上。
3. Rewrite
使用read(2)函數(shù)讀取文件,然后修改再用write(2)函數(shù)寫回。由于文件的空間已經(jīng)分配好,所以這種方式可以很有效地測試文件系統(tǒng)緩存和數(shù)據(jù)傳輸?shù)乃俣取?/span>
Sequential Input
1. Per Char
使用getc()函數(shù)循環(huán) 讀取文件內(nèi)容
2. Block
使用read(2)函數(shù)循環(huán)讀取文件內(nèi)容,有效測試磁盤讀取的效率。
Random Seek
默認(rèn)3個(gè)進(jìn)程作8000次的測試。用read(2)函數(shù)讀取文件的block,同時(shí)有10%的操作是用write(2)函數(shù)將block修改以后寫回文件中。在這個(gè)測試中,如果內(nèi)存容量大于創(chuàng)建的文件大小,那么將會出現(xiàn)比較高的數(shù)值,而這個(gè)數(shù)值可能并不能準(zhǔn)確反映磁盤本身的I/O效率。
Sequential Create和Radom Create
這兩大類測試均是用創(chuàng)建,讀取,刪除大量的小文件來測試磁盤效率。文件名用7位數(shù)字和任意個(gè)數(shù)(0-12)的任意英文字母來組成。在Sequential部分,字母在數(shù)字之后,而Random部分則是字母在數(shù)字之前。
創(chuàng)建文件的最小值和最大值等參數(shù)可以在bonnie++命令行中用-n參數(shù)來控制。
評測.
我們通過bonnie++來測試各種磁盤配置,或者測試各種RAID設(shè)置下的磁盤效率,可以有助于我們對于各個(gè)產(chǎn)品或者各個(gè)方案的磁盤吞吐效率有個(gè)大體認(rèn)識。
在測試結(jié)果的最后一行是用逗號隔開的一列數(shù)字,第一個(gè)位置是我們在運(yùn)行bonnie++時(shí)用-m參數(shù)指定的機(jī)器名,第二個(gè)位置是測試時(shí)生成的文件大小,后面依次是各類測試的結(jié)果。我們將多個(gè)測試的最后一行粘貼到Excel中,然后用圖表功能生成柱狀圖,就可以對多項(xiàng)測試有一個(gè)極為直觀的評測比較。
下面列出了幾種評測的結(jié)果,以后也會陸續(xù)添加更多的評測,同時(shí)歡迎大家將自己的評測結(jié)果mail給我,我會加入到這篇文章中。我的郵件地址是kamus@itpub.net。
SunFire v480 4*(UltraSparc-III+ 1050MHz) 8GRAM 本地光纖硬盤
>bonnie++ -d . -s 16384 -m report -u oracle:dba
Version 1.03 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
report 16G 18703 52 28812 17 10800 12 33700 98 68172 32 260.1 2
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 99 0 +++++ +++ 166 1 101 0 +++++ +++ 205 1
report,16G,18703,52,28812,17,10800,12,33700,98,68172,32,260.1,2,16,99,0,+++++,+++,166,1,101,0,+++++,+++,205,1
SunFire v880 2*(UltraSparc-III+ 900MHz) 4GRAM D2陣列(36G*12,RAID10,2 stripe)
>bonnie++ -d /global/oradata -s 8192 -m d2org -u oracle
Version 1.03 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
d2org 8G 15681 55 26302 23 13877 31 26420 91 88215 49 462.6 5
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 1245 10 +++++ +++ 3541 27 2837 21 +++++ +++ 385 3
d2org,8G,15681,55,26302,23,13877,31,26420,91,88215,49,462.6,5,16,1245,10,+++++,+++,3541,27,2837,21,+++++,+++,385,3
SunFire v880 2*(UltraSparc-III+ 900MHz) 4GRAM D2陣列(36G*8,RAID10,4 stripe)
>bonnie++ -d /global/oradata -s 8192 -m d2new -u oracle
Version 1.03 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
d2new 8G 18275 62 32832 26 25423 55 27444 94 106842 60 549.9 7
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 1723 15 +++++ +++ 5059 40 4821 37 +++++ +++ 653 5
d2new,8G,18275,62,32832,26,25423,55,27444,94,106842,60,549.9,7,16,1723,15,+++++,+++,5059,40,4821,37,+++++,+++,653,5
相關(guān)鏈接
bonnie++主頁
http://www.coker.com.au/bonnie++/
對各種操作系統(tǒng)下磁盤I/O測試軟件的專題站點(diǎn)
http://www.acnc.com/04_02_01.html
該站中還有各種類型RAID的概念描述,優(yōu)缺點(diǎn),