用户工具

站点工具


docs:evaluating:disk_iops_dd

Linux 中用 dd 命令来测试硬盘读写速度
dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。

# 命令格式
dd if=path/to/input_file of=/path/to/output_file bs=block_size count=number_of_blocks

参数说明

主要选项

参数 说明
if=file 输入文件名,缺省为标准输入
of=file 输出文件名,缺省为标准输出.注意:除非你明白自己的操作,只能输出在路径文件,不要输出
到/dev/sda这类磁盘,因为这是磁盘覆盖写入,会导致系统无法使用文件系统故障。
ibs=bytes 一次读入 bytes 个字节(即一个块大小为 bytes 个字节)
obs=bytes 一次写 bytes 个字节(即一个块大小为 bytes 个字节)
bs=bytes 同时设置读写块的大小为 bytes ,可代替 ibs 和 obs
cbs=bytes 一次转换 bytes 个字节,即转换缓冲区大小
skip=blocks 从输入文件开头跳过 blocks 个块后再开始复制
seek=blocks 从输出文件开头跳过 blocks 个块后再开始复制(通常只有当输出文件是磁盘或磁带时才有效)
count=blocks 仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数
conv=conversion[,conversion…] 用指定的参数转换文件
iflag=FLAGS 指定读的方式FLAGS,参见“FLAGS参数说明”
oflag=FLAGS 指定写的方式FLAGS,参见“FLAGS参数说明”

单位

指定数字的地方若以下列字符结尾乘以相应的数字: b=512, c=1, k=1024, w=2, xm=number m

conv 转换参数

参数 说明
ascii 转换 EBCDIC 为 ASCII
ebcdic 转换 ASCII 为 EBCDIC
ibm 转换 ASCII 为 alternate EBCDIC
block 把每一行转换为长度为 cbs 的记录,不足部分用空格填充
unblock 使每一行的长度都为 cbs ,不足部分用空格填充
lcase 把大写字符转换为小写字符
ucase 把小写字符转换为大写字符
swab 交换输入的每对字节
noerror 出错时不停止
notrunc 不截短输出文件
sync 把每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐

FLAGS参数说明

append -append mode (makes sense only for output; conv=notrunc sug-gested)

参数 说明
direct 读写数据采用直接IO方式
directory 读写失败除非是directory
dsync 读写数据采用同步IO
sync 同上,但是针对是元数据
fullblock 堆积满block(accumulate full blocks of input )(iflag only)
nonblock 读写数据采用非阻塞IO方式
noatime 读写数据不更新访问时间

引入time计时命令

计算dd命令执行时间

  1. time有计时作用,dd用于复制,从if读出,写到of;
  2. if=/dev/zero(产生字符)不产生IO,因此可以用来测试纯写速度;
  3. 同理of=/dev/null(回收站、无底洞)不产生IO,可以用来测试纯读速度;
  4. 注意of不要是磁盘(如/dev/sda),此时你要明白是写入操作,磁盘将被覆盖,而无法使用,当然如果你是要写入磁盘且明白原理时,另当别论。一般of均要指向一个路径文件。
  5. 将/tmp/test拷贝到/var则同时测试了读写速度;
  6. bs是每次读或写的大小,即一个块的大小,count是读写块的数量。bs 乘以 count 即为要写入文件的大小,请留意磁盘空间是否会被占满面影响操作系统的服务,或调小参数。

  7. 当写入到驱动盘的时候,我们简单的从无穷无用字节的源 /dev/zero 读取,当从驱动盘读取的时候,我们读取的是刚才的文件,并把输出结果发送到无用的 /dev/null。在整个操作过程中, DD 命令会跟踪数据传输的速度并且报告出结果。

Benchmark

测试读、写、读写

测试前

像任何其他的操作系统一样,GNU/Linux 已经实现的内存管理不仅有效,而且更好。但是,如果有任何进程正在蚕食你的内存,而你想要清除它的话,Linux 提供了一个刷新或清除RAM缓存方法。参考 https://colobu.com/2015/10/31/How-to-Clear-RAM-Memory-Cache-Buffer-and-Swap-Space-on-Linux/
https://www.cnblogs.com/minn/p/9030764.html

写入测试

[root@agent173 ~]# ls -alh /testw.dbf
-rw-r--r-- 1 root root 3.4G Mar 28 12:10 /testw.dbf
#因为/dev//zero是一个伪设备,它只产生空字符流,对它不会产生IO,所以,IO都会集中在of文件中,of文件只用于写,所以这个命令相当于测试磁盘的写能力。命令结尾添加oflag=direct将跳过内存缓存,添加oflag=sync将跳过hdd缓存。
[root@agent173 ~]# time dd if=/dev/zero of=/testw.dbf bs=2M count=10000
^C868+0 records in   #此处提前ctrl+c中止了,中止也会显示统计。
868+0 records out
1820327936 bytes (1.8 GB) copied, 67.0737 s, 27.1 MB/s


real    1m7.330s
user    0m0.000s
sys     0m1.578s
[root@agent173 ~]# time dd if=/dev/zero of=./test2 bs=64k count=1000 oflag=direct
1000+0 records in
1000+0 records out
65536000 bytes (66 MB) copied, 15.7168 s, 4.2 MB/s

real    0m15.746s
user    0m0.002s
sys     0m0.099s
[root@agent173 ~]# time dd if=/dev/zero of=./test2 bs=2M count=1000 oflag=direct
1000+0 records in
1000+0 records out
2097152000 bytes (2.1 GB) copied, 88.6951 s, 23.6 MB/s

real    1m28.697s
user    0m0.002s
sys     0m0.521s
[root@agent173 ~]# time dd if=/dev/sda of=./test2 bs=2M count=1000 oflag=direct
1000+0 records in
1000+0 records out
2097152000 bytes (2.1 GB) copied, 122.39 s, 17.1 MB/s

real    2m2.392s
user    0m0.007s
sys     0m1.732s
[root@agent173 ~]# time dd if=/dev/sda of=./test2 bs=64k count=1000 oflag=direct
1000+0 records in
1000+0 records out
65536000 bytes (66 MB) copied, 14.8945 s, 4.4 MB/s

real    0m15.045s
user    0m0.005s
sys     0m0.148s
[root@agent173 ~]#

读取测试

time dd if=/dev/sdb of=/dev/null bs=4k
#因为/dev/sdb是一个物理分区,对它的读取会产生IO,/dev/null是伪设备,相当于黑洞,of到该设备不会产生IO,所以,这个命令的IO只发生在/dev/sdb上,也相当于测试磁盘的读能力。

测试同时读写能力

time dd if=/dev/sdb of=/testrw.dbf bs=4k
在这个命令下,一个是物理分区,一个是实际的文件,对它们的读写都会产生IO(对/dev/sdb是读,对/testrw.dbf是写),假设它们都在一个磁盘中,这个命令就相当于测试磁盘的同时读写能力。

测试纯写或纯读性能

dd if=/dev/zero of=test bs=8k count=10000 oflag=direct
dd if=test of=/dev/null bs=8k count=10000 iflag=direct
#注意:dd 只能提供一个大概的测试结果,而且是连续 I/O 而不是随机 I/O,理论上文件规模越大,测试结果越准确。 同时,iflag/oflag 提供 direct 模式,direct 模式是把写入请求直接封装成 I/O 指令发到磁盘,非 direct 模式只是把数据写入到系统缓存就认为 I/O 成功,并由操作系统决定缓存中的数据什么时候被写入磁盘。

附录

iostat是一个默认安装的工具,可以在dd的同时显示读写状态。


dd if=/dev/zero of=/dev/sda bs=2M count=1000 oflag=direct

[root@agent172 ~]# dd if=/dev/zero of=/dev/sda bs=2M count=1000 oflag=direct
1000+0 records in
1000+0 records out
2097152000 bytes (2.1 GB) copied, 84.7792 s, 24.7 MB/s #dd执行后输出结果,同时用iostat监控结果。

[root@rac01-node01 /]# iostat -xd 3
Linux 3.8.13-16.2.1.el6uek.x86_64 (rac01-node01)     05/27/2017     _x86_64_    (40 CPU)
Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.05     0.75    2.50    0.50    76.59    69.83    48.96     0.00    1.17   0.47   0.14
scd0              0.00     0.00    0.02    0.00     0.11     0.00     5.25     0.00   21.37  20.94   0.05
dm-0              0.00     0.00    2.40    1.24    75.88    69.83    40.00     0.01    1.38   0.38   0.14
dm-1              0.00     0.00    0.02    0.00     0.14     0.00     8.00     0.00    0.65   0.39   0.00
sdc               0.00     0.00    0.01    0.00     0.11     0.00    10.20     0.00    0.28   0.28   0.00
sdb               0.00     0.00    0.01    0.00     0.11     0.00    10.20     0.00    0.15   0.15   0.00
sdd               0.00     0.00    0.01    0.00     0.11     0.00    10.20     0.00    0.25   0.25   0.00
sde               0.00     0.00    0.01    0.00     0.11     0.00    10.20     0.00    0.14   0.14   0.00


rrqms:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge)
wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。
rsec/s:The number of sectors read from the device per second.
wsec/s:The number of sectors written to the device per second.
rKB/s:The number of kilobytes read from the device per second.   #读
wKB/s:The number of kilobytes written to the device per second.# 写
avgrq-sz:平均请求扇区的大小,The average size (in sectors) of the requests that were issued to the device.
avgqu-sz:是平均请求队列的长度。毫无疑问,队列长度越短越好,The average queue length of the requests that were issued to the device.   
await:每一个IO请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
这个时间包括了队列时间和服务时间,也就是说,一般情况下,await大于svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。
svctm:表示平均每次设备I/O操作的服务时间(以毫秒为单位)。如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好。
如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢。
%util: 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,
所以该参数暗示了设备的繁忙程度,一般地,如果该参数是100%表示磁盘设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。



https://blog.51cto.com/moerjinrong/2286323
https://www.cnblogs.com/wangzhigang/p/3655618.html
http://blog.sina.com.cn/s/blog_71d9aee40101an43.html
#
time dd if=/dev/zero of=./test2 bs=64k count=1000 oflag=direct #直接写到文件
time dd if=/dev/zero of=./test2 bs=2M count=1000 oflag=direct  #直接写到文件

time dd if=/dev/sda of=./test2 bs=64k count=1000 oflag=direct   #读写同时
time dd if=/dev/sda of=./test2 bs=2M count=1000 oflag=direct   #读写同时

docs/evaluating/disk_iops_dd.txt · 最后更改: 2020/09/25 21:49 (modify by Amos)