dd命令測試linux磁碟讀寫速度操作
1、先熟悉兩個特殊的裝置:
(1)/dev/null:回收站、無底洞。
(2)/dev/zero:產生字元。
2、測試磁碟寫能力
time dd if=/dev/zero of=/testw.dbf bs=4k count=100000
rm -f /testw.dbf
因為/dev//zero是一個偽裝置,它只產生空字元流,對它不會產生IO,所以,IO都會集中在of檔案中,of檔案只用於寫,所以這個命令相當於測試磁碟的寫能力。命令結尾新增oflag=direct將跳過記憶體快取,新增oflag=sync將跳過hdd快取。
3、測試磁碟讀能力
time dd if=/dev/sdb of=/dev/null bs=4k
因為/dev/sdb是一個物理分割槽,對它的讀取會產生IO,/dev/null是偽裝置,相當於黑洞,of到該裝置不會產生IO,所以,這個命令的IO只發生在/dev/sdb上,也相當於測試磁碟的讀能力。(Ctrl+c終止測試)
4、測試同時讀寫能力
time dd if=/dev/sdb of=/testrw.dbf bs=4k
rm -f /testrw.dbf
在這個命令下,一個是物理分割槽,一個是實際的檔案,對它們的讀寫都會產生IO(對/dev/sdb是讀,對/testrw.dbf是寫),假設它們都在一個磁碟中,這個命令就相當於測試磁碟的同時讀寫能力。
寫速度:
time dd if=/dev/zero of=test.dbf bs=8k count=300000
其中/dev/zero是一個偽裝置,它只產生空字元流,對它不會產生IO,所以,IO都會集中在of檔案中,of檔案只用於寫,所以這個命令相當於測試磁碟的寫能力。
輸出的結果類似(因為一般更長測試時間更準確,所以可以設定count大一些):
300000+0 records in
300000+0 records out
real 0m36.669s
user 0m0.185s
sys 0m9.340s
所以寫速度為:8*300000/1024/36.669=63.916M/s
讀速度:
time dd if=/dev/sda1 of=/dev/null bs=8k
因為/dev/sdb1是一個物理分割槽,對它的讀取會產生IO,/dev/null是偽裝置,相當於黑洞,of到該裝置不會產生IO,所以,這個命令的IO只發生在/dev/sdb1上,也相當於測試磁碟的讀能力
輸出的結果類似:
448494+0 records in
448494+0 records out
real 0m51.070s
user 0m0.054s
sys 0m10.028s
所以sda1上的讀取速度為:8*448494/1024/51.070=68.61M/s
補充:Windows下安裝Cygwin也可以使用time和dd命令,而且輸出結果中直接包含IO的時間和速度,有興趣的朋友可以試一下,不過我測試下來的速度讀寫都只有40多M每秒,不知道是否是平臺的原因,可能Cygwin的機制和Linux下還是有所不同吧。
如何真正寫磁碟
dd if=/dev/zero of=test bs=64k count=16k 這個是不準確的,因為命令結束的時候資料還沒有真正寫到磁碟上去,因為對磁碟的寫,我們一般是先寫到了快取就返回了。
我們來看dd的幫助頁面對於一些引數的解釋
語法:dd [選項]
if =輸入檔案(或裝置名稱)。
of =輸出檔案(或裝置名稱)。
ibs = bytes 一次讀取bytes位元組,即讀入緩衝區的位元組數。
skip = blocks 跳過讀入緩衝區開頭的ibs*blocks塊。
obs = bytes 一次寫入bytes位元組,即寫入緩衝區的位元組數。
bs = bytes 同時設定讀/寫緩衝區的位元組數(等於設定ibs和obs)。
cbs = byte 一次轉換bytes位元組。
count=blocks 只拷貝輸入的blocks塊。
conv = ASCII 把EBCDIC碼轉換為ASCIl碼。
conv = ebcdic 把ASCIl碼轉換為EBCDIC碼。
conv = ibm 把ASCIl碼轉換為alternate EBCDIC碼。
conv = block 把變動位轉換成固定字元。
conv = ublock 把固定位轉換成變動位。
conv = ucase 把字母由小寫轉換為大寫。
conv = lcase 把字母由大寫轉換為小寫。
conv = notrunc 不截短輸出檔案。
conv = swab 交換每一對輸入位元組。
conv = noerror 出錯時不停止處理。
conv = sync 把每個輸入記錄的大小都調到ibs的大小(用NUL填充)。
the FLAG 引數(完整的看手冊哦,這裡假設你是知道iflag跟oflag的)
-dsync
Use synchronized I/O for data. For the output file, this forces a physical write of output data on each write. For the input file, this flag can matter when reading from a remote file that has been written to synchronously by some other process. Metadata
(e.g., last-access and last-modified time) is not necessarily synchronized.
-sync likewise, but also for metadata
the CONV引數
-fsync
Synchronize output data and metadata just before finishing. This forces a physical write of output data and metadata
dsync跟sync比較好理解,前者是隻同步寫資料,sync同時寫元資料
conv=fsync Synchronize output data and metadata just before finishing 意思也就是在dd命令結束前同步data和metadata,那就是不是每一次寫都同步一次咯,也就是如果我們在dd命令中寫了100次,他可能是等到最後的時候才把他們同步到磁碟。而oflag=dsync是說Use synchronized
I/O for data. For the output file, this forces a physical write of output data on each write,注意這裡邊用詞 a physical write of output data on each write,那就是他是每一次寫都得等到這一次寫寫到了磁碟才進行下一個寫,也就是如果我們使用dd寫100次,他每次寫都是寫到磁碟後才進行下一次寫的。所以這樣當然要比conv=fsync慢一些吧。
在第一個圖中,我們只寫1塊,然後使用oflag=sync與conv=fsync 測出來一個是32.1kb/s 一個是37.8kb/s 差別不大。
但是下一個我寫1000個,conv=fsync就明顯的比oflag=dsync/sync快很多了,所以覺得上面自己扣的英文的理解應該是正確的。
所以在用dd做讀或者寫的時候,應該要注意自己的使用場景,如果需要將資料寫入磁碟的話
dd if=/dev/zero of=test bs=64k count=16k 是不準確的,
而 dd if=/dev/zero of=test bs=64k count=16k conv=fsync 比較準備,他在dd結束前會寫到磁碟,
而dd if=/dev/zero of=test bs=64k count=4k oflag=dsync或者sync 是真正的每寫一次就寫一次磁碟,所以其實可以聽到磁碟啪啪啪的響的。
dd如何繞開cache
如果要規避掉檔案系統cache,直接讀寫,不使用buffer cache,需做這樣的設定
iflag=direct,nonblock
oflag=direct,nonblock
iflag=cio
oflag=cio
direct 模式就是把寫入請求直接封裝成io 指令發到磁碟
非direct 模式,就把資料寫入系統快取,然後就認為io 成功,並由作業系統決定快取中的資料什麼時候被寫入磁碟
hdparm 測試硬碟讀寫速度
安裝:yum install hdparm
語 法:hdparm [-CfghiIqtTvyYZ][-a <快取分割槽>][-A < 0 或 1 >][-c <I/O模式>][-d < 0 或 1 >][-k < 0 或 1 >][-K < 0 或 1 >][-m <分割槽數>][-n < 0 或 1 >][-p <PIO模式>][-P <分割槽數>][-r < 0 或 1 >][-S <時間>][-u < 0 或 1 >][-W < 0 或 1 >][-X <傳輸模式>][裝置] |
補充說明:hdparm可檢測,顯示與設定IDE或SCSI硬碟的引數。 |
參 數: |
-a<快取分割槽> 設定讀取檔案時,預先存入塊區的分割槽數,若不加上<快取分割槽>選項,則顯示目前的設定。 |
-A< 0 或 1 > 啟動或關閉讀取檔案時的快取功能。 |
-c<I/O模式> 設定IDE32位I/O模式。 |
-C 檢測IDE硬碟的電源管理模式。 |
-d< 0 或 1 > 設定磁碟的DMA模式。 |
-f 將記憶體緩衝區的資料寫入硬碟,並清楚緩衝區。 |
-g 顯示硬碟的磁軌,磁頭,磁區等引數。 |
-h 顯示幫助。 |
-i 顯示硬碟的硬體規格資訊,這些資訊是在開機時由硬碟本身所提供。 |
-I 直接讀取硬碟所提供的硬體規格資訊。 |
-k< 0 或 1 > 重設硬碟時,保留-dmu引數的設定。 |
-K< 0 或 1 > 重設硬碟時,保留-APSWXZ引數的設定。 |
-m<磁區數> 設定硬碟多重分割槽存取的分割槽數。 |
-n< 0 或 1 > 忽略硬碟寫入時所發生的錯誤。 |
-p<PIO模式> 設定硬碟的PIO模式。 |
-P<磁區數> 設定硬碟內部快取的分割槽數。 |
-q 在執行後續的引數時,不在螢幕上顯示任何資訊。 |
-r< 0 或 1 > 設定硬碟的讀寫模式。 |
-S<時間> 設定硬碟進入省電模式前的等待時間。 |
-t 評估硬碟的讀取效率。 |
-T 評估硬碟快取的讀取效率。 |
-u< 0 或 1 > 在硬碟存取時,允許其他中斷要求同時執行。 |
-v 顯示硬碟的相關設定。 |
-W< 0 或 1 > 設定硬碟的寫入快取。 |
-X<傳輸模式> 設定硬碟的傳輸模式。 |
-y 使IDE硬碟進入省電模式。 |
-Y 使IDE硬碟進入睡眠模式。 |
-Z 關閉某些Seagate硬碟的自動省電功能。 |
測試硬碟的讀取速度:
普通磁碟測試:
# hdparm -t /dev/sda |
/dev/sda: |
Timing buffered disk reads: 316 MB in 3.02 seconds = 104.71 MB/sec |
# hdparm -T /dev/sda |
/dev/sda: |
Timing cached reads: 19328 MB in 1.99 seconds = 9691.24 MB/sec |
RAID0測試(兩塊盤):
# hdparm -t /dev/sdb |
/dev/sdb: |
Timing buffered disk reads: 622 MB in 3.01 seconds = 206.89 MB/sec |
# hdparm -T /dev/sdb1 |
/dev/sdb1: |
Timing cached reads: 19632 MB in 1.99 seconds = 9844.20 MB/sec |
RAID0測試(三塊盤):
# hdparm -t /dev/sdb |
/dev/sdb: |
Timing buffered disk reads: 846 MB in 3.00 seconds = 281.54 MB/sec |
/dev/sdb: |
# hdparm -T /dev/sdb |
Timing cached reads: 18412 MB in 1.99 seconds = 9229.67 MB/sec |
RAID0測試(四塊盤)
/dev/sdb: |
Timing cached reads: 19608 MB in 1.99 seconds = 9832.76 MB/sec |
Timing buffered disk reads: 860 MB in 3.00 seconds = 286.35 MB/sec |
另外ARID卡測試速度後,每次會警告:
HDIO_DRIVE_CMD( null ) (wait for flush complete) failed: Inappropriate ioctl for device |
參考測試速度方法:time cp -a data2 data2