前言
上一节我们讲道了Fio工具的安装、依赖库以及gcc环境的安装,和简单的使用,今天是进阶讲解,主要讲在性能测试和稳定性测试的一些实战经历,以及一些注意事项。针对磁盘的性能测试各个服务器厂商都会有自己的一套流程,华为 华三 浪潮 等厂商都会对自己的服务器性能进行测试。磁盘性能测试的工具很多,目前主流使用的有:fio 和 iozone
Fio (本文使用的)
iozone (也比较优秀)
fio的安装及流程在上一节:https://blog.csdn.net/u013521274/article/details/107949362
一、Fio性能测试
性能测试主要是测试磁盘的读写性能,一般测试 顺序读,顺序写,随机读,随机写,4种模式。
测试性能指标: bw 平均io带宽
iops 是一个性能测试指标可以简单理解为每秒的读写次数 (该指标在测试结果中显示)
在Fio编写脚本是有很多的参数要进行设置的,如下所示:
参数说明:
filename=/dev/sdb1 测试文件名称,通常选择需要测试的盘的data目录。
direct=1 是否使用directIO,测试过程绕过OS自带的buffer,使测试磁盘的结果更真实。Linux读写的时候,内核维护了缓存,数据先写到缓存,后面再后台写到SSD。读的时候也优先读缓存里的数据。这样速度可以加快,但是一旦掉电缓存里的数据就没了。所以有一种模式叫做DirectIO,跳过缓存,直接读写SSD。
rw=randwrite 测试随机写的I/O
rw=randrw 测试随机写和读的I/O
bs=16k 单次io的块文件大小为16k
bsrange=512-2048 同上,提定数据块的大小范围
size=5G 每个线程读写的数据量是5GB。
numjobs=1 每个job(任务)开1个线程,这里用了几,后面每个用-name指定的任务就开几个线程测试。所以最终线程数=任务数(几个name=jobx)* numjobs。
name=job1: 一个任务的名字,重复了也没关系。如果fio -name=job1 -name=job2,建立了两个任务,共享-name=job1之前的参数。-name之后的就是job2任务独有的参数。
thread 使用pthread_create创建线程,另一种是fork创建进程。进程的开销比线程要大,一般都采用thread测试。
runtime=1000 测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止。
ioengine=libaio 指定io引擎使用libaio方式。libaio:Linux本地异步I/O。请注意,Linux可能只支持具有非缓冲I/O的排队行为(设置为“direct=1”或“buffered=0”);rbd:通过librbd直接访问CEPH Rados
iodepth=16 队列的深度为16.在异步模式下,CPU不能一直无限的发命令到SSD。比如SSD执行读写如果发生了卡顿,那有可能系统会一直不停的发命令,几千个,甚至几万个,这样一方面SSD扛不住,另一方面这么多命令会很占内存,系统也要挂掉了。这样,就带来一个参数叫做队列深度。
Block Devices(RBD) 无需使用内核RBD驱动程序(rbd.ko)。该参数包含很多ioengine,如:libhdfs/rdma等
rwmixwrite=30 在混合读写的模式下,写占30%
group_reporting 关于显示结果的,汇总每个进程的信息。
此外
lockmem=1g 只使用1g内存进行测试。
zero_buffers 用0初始化系统buffer。
nrfiles=8 每个进程生成文件的数量。
磁盘读写常用测试点:
1. Read=100% Ramdon=100% rw=randread (100%随机读)
2. Read=100% Sequence=100% rw=read (100%顺序读)
3. Write=100% Sequence=100% rw=write (100%顺序写)
4. Write=100% Ramdon=100% rw=randwrite (100%随机写)
5. Read=70% Sequence=100% rw=rw, rwmixread=70, rwmixwrite=30
(70%顺序读,30%顺序写)
6. Read=70% Ramdon=100% rw=randrw, rwmixread=70, rwmixwrite=30
(70%随机读,30%随机写)
Fio参数详细的设置说明如上所示,如果还有疑问可以去网上查阅详细资料。
二、代码实战
2.1 测试代码(顺序读写)
#!/bin/sh
export test=fio
echo "fio_write测试"
echo $(date +%F%n%T)
fio -directory=/fiorwtest -rw=write -bs=1M -direct=1 -iodepth 2 -ioengine=libaio -size 1G -thread -numjobs=2 -group_reporting -name=write1M_1Gjob
echo $(date +%F%n%T)
sync
echo 3 > /proc/sys/vm/drop_caches
#ansible all -m shell -a "/tmp/qingli.sh"
echo "write 执行完毕"
echo "fio_read测试"
echo $(date +%F%n%T)
fio -directory=/fiorwtest -rw=read -bs=1M -direct=1 -iodepth 2 -ioengine=libaio -size 1G -thread -numjobs=2 -group_reporting -name=write1M_1Gjob
echo $(date +%F%n%T)
sync
echo 3 > /proc/sys/vm/drop_caches
#ansible all -m shell -a "/tmp/qingli.sh" 196执行197上的
rm -f /fiorwtest/write1M_1Gjob*
echo "read 执行完毕"
如上所示,程序先执行写操作,在执行读操作,最后再把生成的文件删除。执行结果如下如所示。
如上图所示,红线框处的是我们的结果指标,一个是write操作,一个是read操作。
2.2 Fio代码(随机读写)
#!/bin/sh
export test=fio
#随机写
echo "randwrite4k4job"
echo $(date +%F%n%T)
fio -directory=/hlstor/cluster/fubenjuan1 -rw=randwrite -bs=4k -direct=1 -iodepth 8 -ioengine=libaio -size 35G -thread -numjobs=4 -group_reporting -name=randwrite4k_4job
echo $(date +%F%n%T)
sync
echo 3 > /proc/sys/vm/drop_caches
ansible all -m shell -a "/tmp/qingli.sh"
#随机读
echo "randread4k4job"
echo $(date +%F%n%T)
fio -directory=/hlstor/cluster/fubenjuan1 -rw=randread -bs=4k -direct=1 -iodepth 8 -ioengine=libaio -size 35G -thread -numjobs=4 -group_reporting -name=randwrite4k_4job
echo $(date +%F%n%T)
sync
echo 3 > /proc/sys/vm/drop_caches
ansible all -m shell -a "/tmp/qingli.sh"
rm -f /hlstor/cluster/fubenjuan1/randwrite4k_4job*
测试随机读写的 -rw=randwrite、randread
-rw= --设置为randwrite randread 其他无差别
一个参数差别
2.3 Fio代码循环
代码的循环有3种方式,和Python语言和java的循环写法差不多,简单介绍一下例子
for循环一般写法如下所示:
#!/bin/sh
export test=fio
rwmode=("a" "b" "c" "d")
bssize=("1" "2" "3" "4")
for i in ${rwmode[@]}
do
echo $i
echo $(date +%F%n%T)
for j in ${bssize[@]}
do
echo $j
done;
done;
---------------------------第2种----------------------------------
#!/bin/sh
export test=fio
rwmode=("a b c d")
bssize=("1 2 3 4") 差别在这 这个数组的写法
for i in ${rwmode[@]}
do
echo $i
echo $(date +%F%n%T)
for j in ${bssize[@]}
do
echo $j
done;
done;
如上所示,差别在于数组rwmode的写法。两者执行结果一样。
shell在线模拟器 https://c.runoob.com/compile/18
2.3 Fio代码实战循环
循环执行write模式下的4k、1024k 块大小的操作,read模式下4k、1024k 块大小的操作
注意参数的变动需要加 $ 符号
循环的好处:代码量少
循环的缺点:可读性差 (根据自己需要吧)
注意:在这里fio代码中,有了新参数 -runtime=900
在这里面----runtime 参数 单位秒
1、 fio执行runtime的时间推出,即使已经执行完毕也要继续执行知道达到runtime时间。如果设置的话,即使file已被完全读写 或写完,也要执行完runtime规定的时间。它是通过循环执行相同的负载来实现的。
2、设定在记录任何性能信息之前要运行特定负载的时间。这个用来等性能稳定后,再记录日志结果,因此可以减少生成稳定 的结果需要的运行时间。
3、在负债测试时用到,60%的CPU负载下 无故障运行时间。
#!/bin/sh
export test=fio
rwmode=( "write" "read" )
bssize=( "4k" "1024k" )
for j in ${rwmode[@]};
do for i in ${bssize[@]};
do echo "fuse_fenbujuan_$j_$i_1job"
echo $(date +%F%n%T)
fio -directory=/hlstor/fenbujuan1 -rw=$j -bs=$i -direct=1 -iodepth 8 -ioengine=libaio -size 50G -thread -numjobs=1 -runtime=900 -group_reporting -name=$j_$i_1job
echo $(date +%F%n%T)
sleep 60
echo 3 > /proc/sys/vm/drop_caches
done;
done;
三、 性能监控
3.1 iostat 命令
iostat 命令 及结果
iostat -m 1
iostat -x 1
iostat -h 1
每1秒刷新
3.2 实时内存
#!/bin/bash
echo `date` > /root/ansible_test.txt
时间保存到文件
内存的实时状况输出到日志文件
#!/bin/sh
while :
do
free -m >> nei.log
sleep 1
done
-m 是字节 -h 可视化比较好
while :
do
free -h >> /lyfiolog/Memory.log
sleep 1
done
两命令结果如下图:
3.3 sh脚本执行的日志输出,即fio日志输出
该命令可以输出日志到文件,但是执行过程中不能停止,不能干其他事情。
sh fio-liyang-w2.sh >> fioly.log
该命令加上后nohup,后台执行,不影响干其他事
nohup sh fio.sh >> fio.log &
四、稳定性测试
稳定行测或者说是可靠性测试都可以,没有太多的区分,主要目的是检测磁盘在CPU负载55%-80%之间,无故障运行时间,可以对磁盘性能,或者是NAS磁存储系统的健壮性有个很好的度量。
稳定性和上述的性能测试区别不是太大,关键就是要让机器持续的跑,继续跑,跑完了再跑。一般情况需要执行2-3天左右。拿到最终的结果:bw iops 等对稳定性一个很好的度量。
以下为举例:只是一小部分代码,真实项目比这还多。
#!/bin/sh
export test=fio
echo "nfs_fuben"
echo "write4k8job"
echo $(date +%F%n%T)
fio -directory=/data/test1fuben -rw=write -bs=4k -direct=1 -iodepth 8 -ioengine=libaio -size 20G -thread -numjobs=8 -group_reporting -name=write4k_8job
echo $(date +%F%n%T)
echo "read4k8job"
echo $(date +%F%n%T)
fio -directory=/data/test1fuben -rw=read -bs=4k -direct=1 -iodepth 8 -ioengine=libaio -size 20G -thread -numjobs=8 -group_reporting -name=write4k_8job
echo $(date +%F%n%T)
echo "write1M4job"
echo $(date +%F%n%T)
fio -directory=/data/test1fuben -rw=write -bs=1M -direct=1 -iodepth 8 -ioengine=libaio -size 20G -thread -numjobs=4 -group_reporting -name=write1m_4job
echo $(date +%F%n%T)
echo "read1M4job"
echo $(date +%F%n%T)
fio -directory=/data/test1fuben -rw=read -bs=1M -direct=1 -iodepth 8 -ioengine=libaio -size 20G -thread -numjobs=4 -group_reporting -name=write1m_4job
echo $(date +%F%n%T)
五、自己总结测试报告
cluster层 | 4k顺序写 | 4k顺序读 | 1M顺序写 | 1M顺序读 | 4k随机写 | 4k随机读 | 1M随机写 | 1M随机读 |
bw | 36M/s | 65.2M/s | 2384 | 3061 | 120 | 131 | 1952 | 2598 |
iops | 18.9k | 33.4k | 2384 | 3061 | 30.8 | 33.5 | 1952 | 2599 |
如上表所示,这个在cluster层上面的测试,可以是不同卷,分布卷,副本卷,纠错卷,或者是 Fuse、nfs层都可以。本人是以不同的-bs块进行的测试,4k、1M的顺序读写,随机读写,有的结果比较高是因为我电脑是SSD固态硬盘。结果汇总成这样的表格。比较直观。
5.2 注意
在真正的实战项目中,测试机服务器往往要安装Linux 、windows server两个操作系统。Fio执行的时windows有点小差别。Fio命令中,-numjobs 一般设为4 8 10 等,Linux 会将这4个文件都执行完后给出一个最终的值,如本文第一张图所示。
但是windows上,numjobs=4 会出来4个执行结果,这是因为每一个文件都出来了一个结果。那么在测试结果要将这4个结果的bw iops都加起来才是最终的测试结果。
总结:
针对上一节的fio性能测试,做了一个进阶吧,如果有什么问题,可以留言,看到必回复。
本文参考博客:https://blog.csdn.net/qq_14935437/article/details/93749444