一、目的
在Linux系统下使用FIO工具测试不同USB接口版本(2.0/3.0/3.1等)的实际传输速度(顺序读、顺序写)
二、测试环境
-
CPU:Intel(R) Xeon(R) Gold 5320 CPU @ 2.20GHz
-
内存:SAMSUNG 32GB DDR4
-
U盘:USB 3.2 Gen1
三、前提条件
-
已安装Linux操作系统
-
具有root或sudo权限
-
U盘接入服务器
四、测试步骤
1、查看U盘是否接入
lsblk
或查看USB设备与协议命令
cat /sys/kernel/debug/usb/devices
2、安装FIO工具
yum install fio –y
3、执行命令开始测试
顺序读(1M):
fio --filename=/dev/sda --ioengine=libaio --direct=1 --rw=read --bs=1m --numjobs=4 --iodepth=32 --runtime=60 --time_based --thread --norandommap --group_reporting --name=fiotest
顺序写(1M):
fio --filename=/dev/sda --ioengine=libaio --direct=1 --rw=write --bs=1m --numjobs=4 --iodepth=32 --runtime=60 --time_based --thread --norandommap --group_reporting --name=fiotest
五、测试参数
filename:目标盘符/测试设备:filename=/dev/sdb4(可用lsblk命令查询usb对应dev下的节点)
direct: 测试过程绕过机器自带的buffer,使测试结果更真实。
I/O type:rw=Read(顺序读)/write(顺序写)/randread(随机读)/randwrite(随机写)/randrw(随机写和读)
Block Size:单次IO的块文件大小,bs=4k,4k是主流,8k是Mysql和Oracle,16K是MysqlInnodb
I/O size:总共要读写的数据大小,size=10G
Num threads:创建多少进程/线程来并发执行,numjobs=64
iodepth:测试的队列深度,队列深度表示控制器可同时发送给被测设备的指令数目。默认为1。在队列深度增加时,被测设备的访问效率将有明显提升,故性能也有相应提升。 默认对于每个文件来说是 1,可以设置一个更大的值来提高并发度
Runtime:测试运行时间,runtime=300,单位为s
time_based :决定脚本的运行时间,即使 file 已被完全读写或写完,也要执行runtime 规定的时间。它是通过循环执行相同的负载来实现的。例如:time_based
thread:使线程而非进程模拟并发。
norandommap:禁用随机映射(仅对随机 I/O 有意义)。在随机读写(randread
/randwrite
)时,避免重复覆盖相同 LBA(逻辑块地址),确保测试覆盖全盘。虽然当前是顺序写入,但显式禁用随机映射以避免潜在干扰。
group_reporting:汇总所有线程的测试结果,输出汇总报告。
name:为测试任务指定名称。
ioengine:指定 I/O 引擎(即如何提交 I/O 请求)。定义了发起 IO 的方式,可以是内存映射文件,可以是使用普通的读/写,我们可以使用 splice,异步 IO,syslet,甚至 SG(SCSI generic sg),包括sync,pync,vsync,libaio 等。
-
Sync:基本的read,write。通过lseek来作定位;
-
Psync:基本的pread,pwrite,在文件描述符给定的位置偏移上读取或写入数据,pread() 从文件 fd 指定的偏移 offset (相对文件开头) 上读取 count 个字节到buf 开始位置。文件当前位置偏移保持不变。 pwrite() 把缓存区 buf 开头的 count个字节写入文件描述符 fd offset 偏移位置上,文件偏移没有改变。 fd 引用的文件必须是可定位的,属于同步I/O;
-
Vsync:基本的 readv, writev;
-
Libaio: Linux 专有的异步 IO,Linux 仅支持非 buffered IO 的队列行为,libaio 引擎会用这个 iodepth 值来调用 io_setup,准备可以一次提交iodepth 个 IO 的上下文,同时申请iodepth个 io 请求队列用于保持 IO。在压测进行的时候,系统会生成特定的 IO 请求,往 io 请求队列里面提交,当队列里面的IO个数达到 iodepth_batch值的时候,就调用 io_submit 批次提交请求,然后开始调用 io_getevents 开始收割已经完成的 IO。追求的是 IOPS
同步和异步的区别:
-
同步 IO 是指,进程触发 IO 操作后,后面的操作不能进行,只能等待 IO 操作完成或者放弃 IO 操作,保证当前只有一个 IO 操作在进行。
-
异步 IO 是指,触发 IO 操作以后,直接返回,可以继续执行后面的操作,IO 交给内核来处理,完成后内核通知进程 IO 完成。
六、测试结果分析
1. 关键性能指标
-
IOPS:每秒I/O操作数,反映随机读写性能
-
带宽(BW):单位时间传输的数据量(MB/s),反映顺序读写性能
-
延迟(Latency):I/O操作完成时间(us),包括min/max/avg
2. 结果示例分析
带宽 (BW) | 142MiB/s (149MB/s) | 设备顺序读取吞吐量,接近机械硬盘的典型性能(SATA HDD 约 100-200MB/s)。 |
IOPS | 141 | 因块大小为1MB,IOPS=带宽/块大小=142/1≈141,符合预期。 |
平均延迟 | 895.85毫秒 | 从提交I/O到完成的平均时间,较高(正常1MB顺序读延迟应在毫秒级)。 |
CPU占用 | usr=0.08%, sys=0.29% | CPU几乎无压力,瓶颈完全在磁盘I/O。 |
设备利用率 | 99.35% | 磁盘持续满负荷工作,无空闲时间。 |
3. 理论值
基于接口带宽的理论值计算
例:USB2.0:其带宽为480Mbps,换算成字节为480Mbps/8=60MB/s,但这只是理论上的最大数据传输效率,实际会因为协议开销等原因,顺序读写的性能会更低。一般顺序读的速度范围在10-25MB/s,顺序写速度范围为3-10MB/s。
USB版本 | 理论速度 | 实际顺序读速度范围 | 实际顺序写速度范围 |
---|---|---|---|
USB 2.0 | 480 Mbps (60 MB/s) | 25-35MB/s | 3-10MB/s |
USB 3.0(3.1 Gen1/3.2Gen1) | 5 Gbps ((5*1000Mbps)/8=625 MB/s) | 60-150MB/s | 10-45MB/s |
USB 3.1(3.2 Gen2) | 10 Gbps ((10*1000Mbps)/8=1250 MB/s) | ||
USB 3.2 Gen2 X 2 | 20 Gbps ((20*1000Mbps)/8=2500 MB/s) | ||
USB4 1.0 | 40Gbps((40*1000Mbps)/8=5000MB/s) | ||
USB4 2.0 | 80Gbps((80*1000Mbps)/8=10000MB/s) |