服务器性能测试二三事
新到手的机器,从运维手里交接必须要进行一些基本功能的测试。
对于我接手的小文件系统来说,最关键的就是磁盘和网络了。
这篇文章带了下fio和iperf但是没有详细介绍。
下面对fio稍微梳理一下
使用方式:
1 | 安装FIO: |
随机读:
fio -filename=/dev/sda -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=200G -numjobs=10 -runtime=1000 -group_reporting -name=mytest
参数说明:
filename=/dev/sda 测试文件名称,通常选择需要测试的盘的data目录。
direct=1 测试过程绕过机器自带的buffer。使测试结果更真实。
rw=randwrite 测试随机写的I/O
randread 随机读
read 顺序读
write 随机写
randrw 随机读写
bs=16k 单次io的块文件大小为16k
bsrange=512-2048 同上,提定数据块的大小范围
size=5g 本次的测试文件大小为5g,以每次4k的io进行测试。
numjobs=30 本次的测试线程为30.
runtime=1000 测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止。
ioengine= sync 使用read,write和fseek来读写文件
psync 使用pread和pwrite方式读写文件,这种方式读写完以后文件指针不会偏移特别适合随机读写
vsync 使用readv和writev方式读写文件,这种方式能把多个缓冲区的文件一次读写
libaio 使用linux的原生异步IO方式
posixaio 使用posix定义的aio_read和aio_write方式,这种方式在linux下使用pthread进行模拟异步IO,不是很高效
solarisaio solaris的aio
windowsaio windows的aio
mmap 使用内存映射方式,memcpy进行数据复制
splice 使用linux的splice传输数据,使用vmsplice在用户空间和内核之间传输数据
syslet 一个没啥用的异步IO方式
sg SCSI 通用的sg v3 I/O
null 不读写数据,测试fio本身用
net 网络方式,必须提供host/port,如果是接受,那么只有port参数会生效
netsplice 网络方式+splice方式
cpuio 不传递数据,但是安装cpu参数和周期消耗cpu周期
guasi the Generic Userspace Asynchronous Syscall Interface approach to asycnronous I/O.http://www.xmailserver.org/guasi-lib.html
rwmixwrite=30 在混合读写的模式下,写占30%
group_reporting 关于显示结果的,汇总每个进程的信息。
stonewall 等待前一个作业完成
此外
lockmem=1g 只使用1g内存进行测试。
zero_buffers 用0初始化系统buffer。
nrfiles=8 每个进程生成文件的数量。
这是我使用的test.fio脚本
1 | [global] |
测试完成后会输出一大段文字,主要看bw=18967KB/s, iops=1185这一段bw值就是吞吐率,以及iops的值
同时可以用iostat -xk测试
如下 1
2
3
4
5
6avg-cpu: %user %nice %sys %iowait %idle
0.42 0.00 0.26 0.47 98.86
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
hdc 0.01 0.00 0.00 0.00 0.07 0.00 0.03 0.00 24.48 0.00 4.90 4.57 0.00
hda 0.89 8.54 0.74 4.49 12.60 104.22 6.30 52.11 22.32 0.03 5.41 1.01 0.53
rrqm/s
每秒进行merge的读操作数目。
wrqm/s
每秒进行merge的写操作数目。
r/s
每秒完成的读I/O设备次数。
w/s
每秒完成的写I/O设备次数。
rsec/s
每秒读扇区数。
wsec/s
每秒写扇区数。
rkB/s
每秒读K字节数。
wkB/s
每秒写K字节数。
avgrq-sz
平均每次设备I/O操作的数据大小(扇区)。
avgqu-sz
平均I/O队列长度。
await
平均每次设备I/O操作的等待时间(毫秒)。
svctm
平均每次设备I/O操作的服务时间(毫秒)。
%util
一秒中有百分之多少的时间用于I/O操作,或者说一秒中有多少时间I/O队列是非空的。
在从OS Buffer Cache传入到OS Kernel(Linux IO scheduler)的读IO操作的个数实际上是rrqm/s+r/s,直到读IO请求到达OS Kernel层之后,有每秒钟有rrqm/s个读IO操作被合并,最终转送给磁盘控制器的每秒钟读IO的个数为r/w;在进入到操作系统的设备层(/dev/sda)之后,计数器开始对IO操作进行计时,最终的计算结果表现是await,这个值就是我们要的IO响应时间了;svctm是在IO操作进入到磁盘控制器之后直到磁盘控制器返回结果所花费的时间,这是一个实际IO操作所花的时间,当await与svctm相差很大的时候,我们就要注意磁盘的IO性能了;而avgrq-sz是从OS Kernel往下传递请求时单个IO的大小,avgqu-sz则是在OS Kernel中IO请求队列的平均大小。
平均单次IO大小(IO Chunk Size) <=> avgrq-sz
平均IO响应时间(IO Response Time) <=> await
IOPS(IO per Second) <=> r/s + w/s
吞吐率(Throughtput) <=> rkB/s + wkB/s
别人一个不错的例子(I/O 系统 vs. 超市排队)
举一个例子,我们在超市排队 checkout 时,怎么决定该去哪个交款台呢? 首当是看排的队人数,5个人总比20人要快吧? 除了数人头,我们也常常看看前面人购买的东西多少,如果前面有个采购了一星期食品的大妈,那么可以考虑换个队排了。还有就是收银员的速度了,如果碰上了连 钱都点不清楚的新手,那就有的等了。另外,时机也很重要,可能 5 分钟前还人满为患的收款台,现在已是人去楼空,这时候交款可是很爽啊,当然,前提是那过去的 5 分钟里所做的事情比排队要有意义 (不过我还没发现什么事情比排队还无聊的)。
I/O 系统也和超市排队有很多类似之处:
r/s+w/s 类似于交款人的总数
平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
平均服务时间(svctm)类似于收银员的收款速度
平均等待时间(await)类似于平均每人的等待时间
平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
I/O 操作率 (%util)类似于收款台前有人排队的时间比例。
我们可以根据这些数据分析出 I/O 请求的模式,以及 I/O 的速度和响应时间。