以下工具都为 CentOS 自带,可以通过 yum 安装
hdparm
该测试的原理是 hdparm 直接读取磁盘扇区数据,然后衡量读取速度,所以只能测试顺序读取,无法测试写入速度。
hdparm -t /dev/sdb
dd
dd 比较适合用于在所有场景下的顺序写入和读取测试,可以测试块设备,也可以测试文件系统。
顺序写入
dd if=/dev/zero of=./sample bs=1M count=1000 oflag=direct
# 注意加入 oflag=direct 绕开 OS 的 buffer/cache
顺序读取
echo 3 > /proc/sys/vm/drop_caches# /dev/null 不支持 oflag=direct,所以先 drop 一下 cache
dd if=./sample of=/dev/null bs=1M count=1000
对于超过 500MB/s 的顺序读测试,请使用 fio,之前对一个 RAID-0 组的顺序读测试发现,dd 只能跑到 500MB/s,但是 fio 可以达到 900MB/s,顺序写则与 fio 相同。
fio
fio 是一个比较专业的磁盘性能测试工具,当然,使用起来也比较复杂
测试块设备的顺序读取
fio --filename=/dev/sdc --direct=1 --rw=read --bs=1M --ioengine=libaio --iodepth=1 --numjobs=1 --runtime=10 --group_reporting --name=1m-seq-read-test
--ioengine=libaio:使用异步IO API库
--iodepth=1:异步IO同时发送的请求数为1,如果调成 2,每个线程 libaio 会同时发送两个读请求,然后等待它们的返回
--numjobs=1:线程数为 1
--runtime=10:测试时长10秒
--bs=1M:以1M的粒度读取数据
--group_reporting:将多个线程的测试结果进行整合
该测试会开启一个线程,从 /dev/sdc 块设备的起始处以 1M、1M的粒度读取块设备,读取 10 秒,
如果中途 Ctrl-C 让其停止,对测试结果不会有太大的影响,只是缩短测试时间而已。
测试块设备的随机读取
fio --filename=/dev/sdc --direct=1 --rw=randread --bs=4K --ioengine=libaio --iodepth=1 --numjobs=1 --runtime=10 --group_reporting --name=4k-rand-read-test
该测试会单线程以 4K 的粒度随机读取 /dev/sdc 数据,只是测试单线程随机 IO 能力,对于测随机 IO 的 lantency 比较有用。
如果将 numjobs 和 iodepth 都调成 16(一共会有 16*16 = 256 个并发读请求),一般可以将磁盘的 IOPS 跑满。(如果只将 iodepth 调大一点,效果会差一些)
测试结果赏析:
4k-rand-read-test: (g=
0
): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=
32
fio-
2.0
.
13
Starting
1
process
Jobs:
1
(f=
1
): [r] [
100.0
% done] [627K/0K/0K /s] [
156
/
0
/
0
iops] [eta 00m:00s]
4k-rand-read-test: (groupid=
0
, jobs=
1
): err=
0
: pid=
2587
: Sat Aug
20
13
:
45
:
37
2016
read : io=
6384
.0KB, bw=
635977
B/s, iops=
155
, runt= 10279msec # bw(band-width), iops=
155
表示此次测试的 IOPS
slat (usec): min=
8
, max=
75
, avg=
20.27
, stdev=
4.66
clat (msec): min=
2
, max=
1369
, avg=
205.66
, stdev=
200.77
# clat(complete-lantency), stdev 是正态分布的意思
lat (msec): min=
2
, max=
1369
, avg=
205.68
, stdev=
200.77
clat percentiles (msec):
|
1
.00th=[
6
],
5
.00th=[
13
],
10
.00th=[
21
],
20
.00th=[
41
],
|
30
.00th=[
71
],
40
.00th=[
101
],
50
.00th=[
141
],
60
.00th=[
196
],
|
70
.00th=[
260
],
80
.00th=[
343
],
90
.00th=[
474
],
95
.00th=[
611
],
|
99
.00th=[
898
],
99
.50th=[
1004
],
99
.90th=[
1270
],
99
.95th=[
1369
],
|
99
.99th=[
1369
]
bw (KB/s) : min=
435
, max=
694
, per=
98.70
%, avg=
612.90
, stdev=
62.44
lat (msec) :
4
=
0.38
%,
10
=
3.07
%,
20
=
5.89
%,
50
=
14.29
%,
100
=
15.98
%
lat (msec) :
250
=
29.14
%,
500
=
22.62
%,
750
=
6.27
%,
1000
=
1.82
%,
2000
=
0.56
%
cpu : usr=
0.31
%, sys=
0.44
%, ctx=
1636
, majf=
0
, minf=
54
IO depths :
1
=
0.1
%,
2
=
0.1
%,
4
=
0.3
%,
8
=
0.5
%,
16
=
1.0
%,
32
=
98.1
%, >=
64
=
0.0
%
submit :
0
=
0.0
%,
4
=
100.0
%,
8
=
0.0
%,
16
=
0.0
%,
32
=
0.0
%,
64
=
0.0
%, >=
64
=
0.0
%
complete :
0
=
0.0
%,
4
=
99.9
%,
8
=
0.0
%,
16
=
0.0
%,
32
=
0.1
%,
64
=
0.0
%, >=
64
=
0.0
%
issued : total=r=
1596
/w=
0
/d=
0
,
short
=r=
0
/w=
0
/d=
0
Run status group
0
(all jobs):
READ: io=6384KB, aggrb=621KB/s, minb=621KB/s, maxb=621KB/s, mint=10279msec, maxt=10279msec
Disk stats (read/write):
sdc: ios=
1574
/
0
, merge=
0
/
0
, ticks=
315209
/
0
, in_queue=
321729
, util=
98.29
%
|
测试块设备的顺序写入
fio --filename=/dev/sdc --direct=1 --rw=write --bs=1M --ioengine=libaio --iodepth=1 --numjobs=1 --runtime=30 --group_reporting --name=1M-seq-write-test
fio 将会以1个线程,1MB 的粒度向块设备写入数据
调整 --iodepth 到 8,相当于以 8MB 的粒度写入
调大 --numjobs,意义不大,每个线程都是独立的从头开始写,比如 --numjobs = 4 将会产生 3 次 overwrite,磁盘或 RAID 卡有可能会将这些 overwrite 合并,而只向磁盘写入一次,但从外面看,是 4 个 write 的流量
测试块设备的随机写入
注意,这个测试会破坏该块设备上的数据,请不要在有数据磁盘上作测试
fio --filename=/dev/sdc --direct=1 --rw=randwrite --bs=4K --ioengine=libaio --iodepth=1 --numjobs=1 --runtime=10 --group_reporting --name=4k-rand-write-test
可以调整 iodepth, numjobs, bs 来评估不同的测试结果
测试文件系统
只需要将 --filename 指向一个准备好的文件,即可进行测试。
如果不指定 --filename,需要指定 --size(每个线程会在当前目录创建一个指定 size 的文件,如果有 read 的测试,该文件在测试前会被创建并填充,如果只是 write 测试,则只是创建,然后 truncate 该测试文件)
fio 参考:
- https://www.linux.com/learn/inspecting-disk-io-performance-fio
- http://www.storagereview.com/fio_flexible_i_o_tester_synthetic_benchmark
- https://tobert.github.io/post/2014-04-17-fio-output-explained.html
Tips
- 打开磁盘写 cache
- hdparm -W1 /dev/sda
- RAID 性能
- RAID-1/5/6 的单线程顺序写入性能很差,可能达不到裸盘的 50%,多线程 + 高iodepth 顺序写入性能要好一点,大约可以达到单盘的 100%
- 原因是每次写入都需要同时写入不同的磁盘
- 打开 WB 之后,写入效率可以达到裸盘的 100% ~ 150%
- RAID-1/5/6 的读取性能很高,可以达到裸盘效率的 100% x 数据盘数量
- 原因是每一次读取,都可以从多块盘上将数据读取出来
- RAID-0 的读写性能相当于所有裸盘性能的聚合,即使不开启 WB 也没有任何影响
- RAID-1/5/6 的单线程顺序写入性能很差,可能达不到裸盘的 50%,多线程 + 高iodepth 顺序写入性能要好一点,大约可以达到单盘的 100%
- 使用 fio 进行顺序读/写测试时,不应该使用多线程,那样会使 IO 不连续