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 outreal 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慢一些吧。

linux如何测试nfs磁盘io性能 linux如何测试磁盘读写速度_数据

linux如何测试nfs磁盘io性能 linux如何测试磁盘读写速度_缓存_02

在第一个图中,我们只写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