linux硬盘性能测试
作为一个运维来说,有的时候需要进行某些方面的测试来辅助以选择,如云主机的性能测试,机房网络测试等,这里总结了一下服务器硬盘的读写压力测试。还记得刚入行的时候,领导交代要对十几个不同品牌的云主机进行测试对比分析,当时测试硬盘读写的工具就是dd,现在知道还有很多其他很好的工具,下面列举一二。
这里一定要明确一个概念,那就是尽管我们使用IOPS来计算传输速度,但是实际上传输速度和IOPS是没有直接关系,在没有缓存的情 况下它们共同的决定因素都是对磁盘系统的访问方式以及单个IO的大小。对磁盘进行随机访问时候我们可以利用IOPS来衡量一个磁盘系统的性能,此时的传输 速度不会太大;但是当对磁盘进行连续访问时,此时的IOPS已经没有了参考的价值,这个时候限制实际传输速度却是磁盘的最大传输速度。因此在实际的应用当 中,只会用IOPS来衡量小IO的随机读写的性能,而当要衡量大IO连续读写的性能的时候就要采用传输速度而不能是IOPS了。
一般而言,磁盘读写有两种方式:BufferIO、DirectIO,DirectIO可以更好的了解纯磁盘读写的性能.在磁盘测试中最关心的几个指标分别为: iops(每秒执行的IO次数)、bw(带宽,每秒的吞吐量)、lat(每次IO操作的延迟)。 当每次IO操作的block较小时,如512bytes/4k/8k等,测试的主要是iops。当每次IO操作的block较大时,如256k/512k/1M等,测试的主要是bw。
博文来自:www.51niux.com
一、 第一个工具:dd
dd这个命令有很多作用,这里我们首先先要明确dd测试的方式:
dd bs=4k count=10240 if=/dev/zero of=test #没有加任何参数,dd默认的方式不包括“同步(sync)”命令。也就是说,dd命令完成前并没有让系统真正把文件写到磁盘上。所以以上命令只是单纯地把这些数据读到内存缓冲当中(写缓存[write cache])。所以你得到的将是一个超级快的速度。因为其实dd给你的只是读取速度,直到dd完成后系统才开始真正往磁盘上写数据,但这个速度你是看不到了。所以如果这个速度很快,没有什么作用。
dd bs=4k count=10240 if=/dev/zero of=test; sync #和前面1中的完全一样。分号隔开的只是先后两个独立的命令。当sync命令准备开始往磁盘上真正写入数据的时候,前面dd命令已经把错误的“写入速度”值显示在屏幕上了。所以你还是得不到真正的写入速度。
dd bs=4k count=10240 if=/dev/zero of=test conv=fdatasync #加入这个参数后,dd命令执行到最后会真正执行一次“同步(sync)”操作,所以这时候你得到的是读取数据到内存并写入到磁盘上所需的时间,这样算出来的时间才是比较符合实际使用结果的。
dd bs=4k count=10240 if=/dev/zero of=test oflag=dsync #加入这个参数后,dd在执行时每次都会进行同步写入操作。也就是说,这条命令每次读取4后就要先把这4k写入磁盘,然后再读取下面这4k,一共重复10240次。这可能是最慢的一种方式了,因为基本上没有用到写缓存(write cache)。可以模拟数据库的插入操作,所以很慢,也是用来测试硬盘性能标准的一条标杆。
综上所述,所以如果我们如果用dd测试硬盘性能的话,如果像测试硬盘抛出缓存的纯读写操作的话,就用第四条,当然如果硬盘有raid的话,也要进系统BIOS关闭掉RAID缓存。
测试服务器硬盘的纯写性能:
[root@linux ~]# dd if=/dev/zero of=/home/test.write bs=4k count=103000 oflag=dsync #写一个块大小为4k,写103000个块,总大小为422MB的文件
测试服务器硬盘的读性能:
[root@linux ~]# dd if=/home/test.write of=/dev/null bs=4k count=103000 oflag=dsync #此前我们写的文件是422MB的,然后读取一下
测试服务器硬盘的读写性能:
[root@linux ~]# dd if=/dev/sda3 of=/home/test.write bs=4k count=103000 oflag=dsync #/home/test.write所挂载的分区就是/dev/sda3
缺点:不是一款专业的测试软件,受服务器内存影响较大,测试数据一般是服务器内存的2倍,不能显示iops值。不能显示随机读写性能。一般用来测试大文件的顺序读写性能。
优点:可以进行磁盘同时读写的测试,也可以加不同的参数来进行测试,比如说像fio一样跳过缓存进行磁盘的真实写入测试就可以加参数oflag=dsync,模拟生产环境就可以加参数conv=fdatasync。
博文来自:www.51niux.com
二、第二个工具:iozone
Iozone主要用来测试操作系统文件系统性能的测试工具。
Iozone的安装:
wget http://www.iozone.org/src/current/iozone-3-434.src.rpm
rpm -ivh iozone-3-434.src.rpm
tar xf iozone3_434.tar
cd iozone3_434/src/current/
make linux
测试模式:
IOzone的测试过程中可以使用-i参数指定多个测试模式,例如-i 0 -i 1 -i 2。
0=write/rewrite
1=read/re-read
2=random read/random write
3=backwards read
4=re-write-record
5=stride-read
6=fwirte/re-fwrite
7=fread/re-fread
8=random mix
9=pwrite/re-pwrite
10=pread/re-pread
11=pwritev/re-pwritev
12=preadv/re-preadv
常见参数:
-a 自动模式(花费很长时间,注意),测试记录块大小从4k到16M,测试文件从64k到512M.文件大于32MB时停止使用低于64k以下记录块以节省时间 -y 设置自动模式下的记录块最小值,-q设置自动模式下的记录块最大值 -n 设置自动模式下的文件最小值,-g设置自动模式下的文件最大值 -B 使用mmap()接口来创建并访问测试文件.即以读写内存的方式访问那个块来完成文件I/O -i 指定运行于哪种测试模式.可以使用-i 0 -i 1 -i 2进行多个测试 -I 对所有文件操作使用DIRECT I/O.通知文件系统所有操作跳过缓存直接在磁盘上操作 -R 将结果导出到Excel文件 -b 指定导出结果的Excel文件名 -f 指定测试的文件名 -F 进程throughput模式(多线程)测试时的文件名,请注意,有多少个线程,后面就应该跟多个个文件名 -c 计算时间时包含close()参数,<strong>对于NFS3分区将非常有用</strong>-G 对mmap文件使用msync(MS_SYNC)。告诉操作系统在mmap空间的所有数据需要被<strong>同步</strong>的写到磁盘上 -D 对mmap文件使用MSYNC(MS_ASYNC)。告诉操作系统在mmap空间的所有数据需要被<strong>异步</strong>的写到磁盘上 -o 写操作都同步写入到磁盘中,即强制写入完成以后再返回benchmark -r 设置记录块大小 -s 设置测试文件大小(<strong>建议是内存的2倍</strong>) -I 对所有文件操作使用DIRECT I/O,通知文件系统所有操作跳过缓存直接在磁盘上操作 -t 使用throughput模式(多线程),并指定线程或进程数 -l 设置最小进程数.在测试过程允许用户设置的最小进程或线程数.需要配合-u选项使用 -u 设置最大进程或线程数,需要配合-l参数使用
常用测试:
./iozone -f /home/iozone.wks -s 40g -i 0 -i 1 -i 2 -y 4k -q 4k # -f指定写入一个 /home/iozone.wks文件,-s指定一个40G的文件,-i 指定的模式,-y -q是指定文件的块大小范围。
./iozone -a -i 0 -i 1 -g 40G -Rb out.xls #-R -b 将自动的测试结果导入到指定文件名的xls文件中
缺点:不能单独测试读操作,不能测试磁盘的同时读写性能,不能显示iops。
优点:测试数据还是比较接近生产场景,网友推荐的一款专业测试软件。可以加 -I参数跳过缓存进行读写测试,像fio一样模拟跳过一切缓存后磁盘的写入情况。
博文来自:www.51niux.com
三、第三个工具:fio
FIO是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio 等等。 fio下载地址: http://freshmeat.net/projects/fio/
应用程序使用IO通常有二种方式:同步和异步。 同步的IO一次只能发出一个IO请求,等待内核完成才返回,这样对于单个线程iodepth总是小于1,但是可以通过多个线程并发执行来解决,通常我们会用16-32个线程同时工作把iodepth塞满。 异步的话就是用类似libaio这样的linux native aio一次提交一批,然后等待一批的完成,减少交互的次数,会更有效率。
fio的安装:
wget http://brick.kernel.dk/snaps/fio-2.0.7.tar.gz
yum install libaio-devel
tar zxf fio-2.0.7.tar.gz
cd fio-2.0.7
make && make install
fio的用法:
随机写:
fio -filename=/home/1.txt -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=20G -numjobs=30 -runtime=100 -group_reporting -name=mytest
可以看到随机写为:97MB/S,iops为25013
其实这里有一个坑的,网上的文章基本都是读写一个大文件,如100G或者20G等,然后呢再补加一个-runtime=100时间,然后呢,如果你仔细观察的话,你会发现一开始一开始实时的数据还算正常,但是最后得出的数据往往很大,甚至有些大的离谱。这就是因为以你实际读速度或者写速度,你根本完不成这么大的一个文件的读写操作,在你定义的一个很短的时间内,但是为什么要加这个时间呢,因为如果你测试的文件写的太大了,你不加时间让它自己完成吧,好吧可能好几个小时出去了,因为我们一般测试读写都是跳过所有的缓存,是为了测试硬盘的IO性能嘛。
比如你测试读,你设置了100G的文件,然后定义了一个-runtime=500,然后前两分钟你观察最下方中间的位置会有一个[多少KB/S],前两三分钟还是正常的,后1分钟可能就直接几千MB/S那么跑了,因为你规定了500秒读完100G嘛。然后最后一平均,得数据就不是很准了。
所以这里建议你可以先加上时间来观察一下此硬盘实际的每秒的写或者读性能,然后你设立一个合理的文件大小,不要设置那么大,然后不加runtime,让它自己随心所欲的跑,最后的数据比较贴近实际。又或者呢你就是想通过观察实时显示的数据来推测性能,那就可以把测试文件写大小,测试时间尽量调大一点。
当然如果你要查看IOS等最后那个结果汇总的值的话,建议还是测试文件小点,然后不设置runtime让测试程序无束缚的跑起来,就不用赶进度了而误报了。
说明:
filename=/home/1.txt 测试文件的名称
direct=1 测试过程绕过机器自带buffer,使测试结果更真实
iodepth 1 同步IO
rw=randwrite 测试随机写的I/O
ioengine=psync io引擎使用pync方式
bs=4k 单次io的块文件大小为4k
size=20G 本次的测试文件大小为20G
numjobs=30 本次测试线程为30
runtime=100 测试时间为100秒,如果不指定时间的话,会直到把这20G文件写完才结束
group_reporting 关于显示结果的,汇总每个进程的信息
name=mytest 测试名称为mytest
随机读:
fio -filename=/home/1.txt -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=20G -numjobs=30 -runtime=100 -group_reporting -name=mytest
顺序写:
fio -filename=/home/1.txt -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=20G -numjobs=30 -runtime=100 -group_reporting -name=mytest
顺序读:
fio -filename=/home/1.txt -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=20G -numjobs=30 -runtime=100 -group_reporting -name=mytest
混合随机读写(rwmixwrite=70 在混合读写的模式下,,读占70%):
fio -filename=/home/1.txt -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=20G -numjobs=30 -runtime=100 -group_reporting -name=mytest
fio参数使用:
测试任务相关的参数以及含义:
--output= : 将测试结果输出到文件,等号后是文件名字。
--runtime= : 限制运行时间,单位为妙。
--name= : 字符串,测试项目名称。
--description= : 字符串,测试项目描述。
--filename= : 测试文件,也可以指定到裸设备上。
--size= : 测试文件大小。最小单位是GB吧,不知道怎么设置MB。
--filesize= : 单独的文件大小,也可以是一个范围,fio在设定的size之内随机地选择大小,如果没有指定,则每个子文件大小相同。
读/写方式参数及含义如下:
--readwrite= : 测试读/写方式,可以是下面的选项:
read : 顺序读
write : 顺序写
trim : 顺序trim,只支持linux块设备
randread : 随机读
randwrite : 随机写。
randtrim : 随机trim,只支持linux块设置。
rw,readnwrite : 混合读/写。
测试块大小参数及含义如下:
--blocksize= 或者 --bs= : 测试的时候读写块大小,可以是4K,8K,1M等。
运行相关参数及含义如下:
--max-job= : 运行的最高线程
--zero_buffers : 如果使用这个参数,fio会初始化IO缓存,并默认使用随机的数据填满缓存。
--refill_buffers : 强制重新填写读/写缓存。
--iodepth=io : 队列深度,默认是1.
--numjobs= : 线程数量
--group_reporting : 汇总每个进程的信息。
--lockmem= : 固件测试的时候内存大小,如2GB
--nrfiles= : 每个进程生成文件的数量,比如8.
另外:Window操作系统下的测试工具一般用:iometer