磁盘性能测试
磁盘性能测试标准
1
2
3
4
1. 读写顺序: 随机读写、顺序读写
2. 读写块大小: 4k、16k、64k
3. 读写文件大小: **G
磁盘性能测试
1. dd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
常见选项:
bs=<size>:设置块大小。例如,bs=1M 表示每个块 1 MB。指定读写操作的块大小,即每次读写的字节数。这与操作系统文件系统的块大小不同,而是指在 dd 操作过程中使用的传输单位
count=<number>:指定读取的块数。例如,count=10 表示读取 10 个块。
skip=<number>:跳过输入文件开头的块数。例如,skip=5 表示跳过前 5 个块。
seek=<number>:跳过输出文件开头的块数。例如,seek=5 表示在写入数据前跳过前 5 个块。
oflag=<flags>:设置输出文件的标志。例如,oflag=dsync 表示在写入数据后确保数据已同步到磁盘。
iflag=<flags>:设置输入文件的标志。例如,iflag=fullblock 表示确保每个读取块的完整性。
1. 写入性能测试
dd if=/dev/zero of=/path/to/testfile bs=1G count=1 oflag=dsync
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 1.0158 s, 1.1 GB/s
if=/dev/zero:输入文件,/dev/zero 是一个产生零字节的特殊设备文件。
of=/path/to/testfile:输出文件,你可以将 /path/to/testfile 替换为你要测试的实际路径。
bs=1G:块大小为 1GB。你可以根据需要调整块大小(例如 4M 表示 4MB)。
count=1:只写入 1 个块。
oflag=dsync:在写入数据后,确保数据已经同步到磁盘,这样可以更准确地测量性能。
2. 读取性能测试: 会产生多余文件,占用空间,测试后及时删除
dd if=/tmp/testfile of=/dev/null bs=1G
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 2.04944 s, 524 MB/s
if=/tmp/testfile:输入文件,你可以使用之前写入的文件。
of=/dev/null:输出文件,/dev/null 是一个丢弃所有输入的特殊设备文件。
bs=1G:块大小为 1GB。可以根据需要调整块大小。
其他用法
======================
备份整个磁盘:
将整个磁盘 /dev/sda 备份到一个镜像文件 backup.img:
dd if=/dev/sda of=backup.img bs=4M
恢复磁盘镜像:
将镜像文件 backup.img 恢复到磁盘 /dev/sda
dd if=backup.img of=/dev/sda bs=4M
创建启动盘:
将 ISO 文件 ubuntu.iso 写入到 U 盘 /dev/sdX(注意替换 /dev/sdX 为实际设备)
dd if=ubuntu.iso of=/dev/sdX bs=4M status=progress
创建文件填充:
创建一个大小为 1 GB 的文件 largefile,并用零填充:
dd if=/dev/zero of=largefile bs=1G count=1
复制文件:
将文件 source_file 复制到 destination_file:
dd if=source_file of=destination_file
测试写入速度:
> dd if=/dev/zero of=testfile bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.459133 s, 228 MB/s
100+0 records in:输入了 100 个块。
100+0 records out:输出了 100 个块。
104857600 bytes copied:复制了 104,857,600 字节。
228 MB/s:写入速度为 228 MB/s。
2. fio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 安装
yum install fio -y
apt install fio
或者
wget https://brick.kernel.dk/snaps/fio-3.37.tar.gz(最新)
tar -xzvf fio-3.37.tar.gz
cd fio-3.37
make
sudo make install
# 命令参数
filename=/dev/emcpowerb 支持文件系统或者裸设备,-filename=/dev/sda2或-filename=/dev/sdb
direct=1 测试过程绕过机器自带的buffer,使测试结果更真实
iodepth I/O 队列深度,控制并行的 I/O 请求数
ioengine I/O 引擎,如 psync 表示同步 I/O
thread 使用线程模式执行 I/O 操作
rw=randwread 测试随机读的I/O
rw=randwrite 测试随机写的I/O
rw=randrw 测试随机混合写和读的I/O
rw=read 测试顺序读的I/O
rw=write 测试顺序写的I/O
rw=rw 测试顺序混合写和读的I/O
bs=4k 单次io的块文件大小为4k
bsrange=512-2048 同上,提定数据块的大小范围
size=5g 本次的测试文件大小为5g,以每次4k的io进行测试
numjobs=30 本次的测试线程为30
runtime=1000 测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止
rwmixwrite=30 在混合读写的模式下,写占30%
rwmixread=30 在混合读写的模式下,读占30%
group_reporting 关于显示结果的,汇总每个进程的信息
name 为测试任务指定一个名称
此外
lockmem=1g 只使用1g内存进行测试
zero_buffers 用0初始化系统buffer
nrfiles=8 每个进程生成文件的数量
场景:
1. 100%随机,100%读, 4K
fio -filename=/dev/sda1 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100read_4k
--filename=/dev/sda1: 测试目标是 /dev/sda1 分区。
--direct=1: 使用直接 I/O 模式,绕过系统缓存。
--iodepth=1: I/O 队列深度为 1,表示每次只发出一个 I/O 请求,等待完成后再发下一个。
--thread: 使用线程模式执行任务。
--rw=randread: 执行随机读操作。
--ioengine=psync: 使用同步 I/O 引擎。
--bs=4k: 每次 I/O 操作的数据块大小为 4KB。
--size=1000G: 总共测试 1000GB 的数据量。
--numjobs=50: 启动 50 个并行任务。
--runtime=180: 运行时间为 180 秒(3 分钟)。
--group_reporting: 输出汇总报告,显示所有任务的整体性能。
--name=rand_100read_4k: 测试任务名称为 rand_100read_4k
执行命令后,fio 将生成一份详细的测试报告,包括以下内容:
读/写吞吐量:每秒读写的数据量(通常以 MB/s 或 IOPS 为单位)。
延迟:I/O 操作的平均、最小、最大和百分位延迟时间。
CPU 使用率:测试期间的 CPU 使用情况。
错误率:报告任何 I/O 错误
=============================执行结果=============================================
rand_100read_4k: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1
...
fio-3.7
Starting 50 threads
Jobs: 50 (f=50): [r(50)][100.0%][r=7958KiB/s,w=0KiB/s][r=1989,w=0 IOPS][eta 00m:00s]
rand_100read_4k: (groupid=0, jobs=50): err= 0: pid=11438: Mon Aug 19 17:31:38 2024
read: IOPS=3787, BW=14.8MiB/s (15.5MB/s)(2668MiB/180349msec)
clat (usec): min=7, max=1816.8k, avg=13190.06, stdev=58772.49
lat (usec): min=7, max=1816.8k, avg=13190.12, stdev=58772.49
clat percentiles (usec):
| 1.00th=[ 18], 5.00th=[ 26], 10.00th=[ 42],
| 20.00th=[ 52], 30.00th=[ 78], 40.00th=[ 163],
| 50.00th=[ 314], 60.00th=[ 816], 70.00th=[ 1876],
| 80.00th=[ 5735], 90.00th=[ 23987], 95.00th=[ 60556],
| 99.00th=[ 250610], 99.50th=[ 400557], 99.90th=[ 792724],
| 99.95th=[1010828], 99.99th=[1367344]
bw ( KiB/s): min= 0, max= 2602, per=2.16%, avg=326.69, stdev=327.04, samples=14707
iops : min= 0, max= 650, avg=81.57, stdev=81.82, samples=14707
lat (usec) : 10=0.01%, 20=2.14%, 50=16.68%, 100=14.27%, 250=13.96%
lat (usec) : 500=8.17%, 750=3.90%, 1000=3.28%
lat (msec) : 2=8.37%, 4=6.49%, 10=6.84%, 20=4.73%, 50=5.31%
lat (msec) : 100=2.78%, 250=2.08%, 500=0.67%, 750=0.21%, 1000=0.06%
cpu : usr=0.01%, sys=0.05%, ctx=683994, majf=3, minf=305
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=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=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=683049,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
READ: bw=14.8MiB/s (15.5MB/s), 14.8MiB/s-14.8MiB/s (15.5MB/s-15.5MB/s), io=2668MiB (2798MB), run=180349-180349msec
Disk stats (read/write):
sda: ios=811179/484, merge=317/42, ticks=18406380/26023, in_queue=18442783, util=100.00%
=================================================================================
2. 100%随机,70%读,30%写 4K
fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k
3. 测试nfs等网络设备
其他不变, --directory=/mnt/nfs: 指定 NFS 挂载点作为测试目录
附录
判断进程文件读写方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1. strace
strace -e trace=lseek,read,write -p <pid>
-e trace=lseek,read,write: 只跟踪 lseek、read 和 write 系统调用。
<pid>: 目标进程的 PID
如果看到频繁的 lseek 调用,并且 read 或 write 操作在非连续的位置进行,这通常表明文件正在进行随机读写
2. dstat
dstat --top-io --top-bio
--top-io: 显示进程 I/O 活动。
--top-bio: 显示块设备 I/O 活动。
通过观察 I/O 活动的频率和模式,您可以推断文件是否在进行随机读写, 您提供的输出似乎是来自 dstat 或类似工具的报告,
如何判断随机读写:
在这个输出中,您可以看到与 I/O 操作相关的进程以及它们的 I/O 消耗情况。这些信息可以帮助您识别哪些进程可能正在执行随机读写:
> 频繁的小块 I/O 操作:如果一个进程执行了大量的小块读写操作(例如几千字节或几百字节),这通常表明该进程正在执行随机 I/O 操作,而不是顺序 I/O 操作。
> 块 I/O 的分散性:如果一个进程的块 I/O 操作非常分散,且数据量不是连续的大块数据,这也可能是随机 I/O 的一个指标
================================================================================
/usr/bin/dstat:2619: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses
import imp
----most-expensive---- ----most-expensive----
i/o process | block i/o process
systemd 1497k 784k|systemd 1513k 679k
sshd 6403k 955k|nfsd 0 32k
python 3827k 9632B|systemd-jou 0 128k
sshd 583k 298k|nfsd 0 28k
sshd 6193k 728k|nfsd 0 20k
nvitop 3696k 0 |nfsd 0 32k
python 3799k 9500B|nfsd 0 24k
sshd 6020k 724k|systemd-jou 0 124k
python 4000k 12k|nfsd 0 32k
python 4000k 12k|nfsd 0 36k
sshd 6207k 731k|nfsd 0 16k
python 3836k 9632B|nfsd 0 40k
irqbalance 730k 0 |nfsd 0 36k
sshd 6022k 725k|systemd-jou 0 124k
nvitop 3696k 0 |java 0 220k
python 3799k 9498B|nfsd 0 32k
sshd 6389k 954k|nfsd 0 32k
...
...
================================================================================
分析输出:
1. I/O Process:列出了每个进程的 I/O 活动情况,包括读取和写入数据的大小。Python 脚本显然是最耗费 I/O 资源的进程之一。
2. Block I/O Process:列出了涉及到块设备的 I/O 操作,也就是直接读写磁盘的操作。系统守护进程(如 systemd 和 nfsd)似乎参与了大量的块 I/O 操作
读写操作时传输的数据块大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
strace:最直接的方式来查看每次读写操作的块大小,适用于进程级别的分析。
iostat、pidstat:适合整体系统或设备级别的分析,但不会直接显示每次操作的块大小。
perf、blktrace:适合深入分析块设备层面的 I/O 请求大小。
1. strace
strace -e trace=read,write -p 1234
显示每次 read 和 write 调用的参数,包括传输的数据大小
eg:
read(3, "data", 4096) = 4096
write(4, "data", 512) = 512
2. blktrace
sudo blktrace -d /dev/sdX -o - | blkparse -i -
/dev/sdX:您想要监控的设备(例如 /dev/sda)。
blkparse 解析输出,并显示每个 I/O 请求的详细信息,包括请求的大小
apt install blktrace
本文由作者按照
CC BY 4.0
进行授权