跳转到内容

性能测试:fio 与 iperf3 ​

「NAS 慢」得先量化才能解决。读完这一篇,你能分别测出网络、磁盘和端到端的速度,读懂结果,并且用「谁最低谁就是瓶颈」的方法找到限制速度的那一层。

开始之前 ​

  • 命令里 OMV 的 shell 指 SSH 或本机控制台,root 身份;客户端电脑指你访问 NAS 的那台电脑。
  • 测试会产生大量读写。选没有人使用的时间,不要在备份、scrub、RAID 重建的同时测。
  • 本文不给「应该测到多少」的数字。你的硬件不同,结果不同,重要的是同一台机器改动前后的对比,以及三层结果之间的对比。

fio 写测试只能写文件,绝不能对着磁盘设备写

影响范围:fio 可以直接读写磁盘设备(例如 /dev/sdb)。对设备做写测试会直接覆盖设备上的数据,包括文件系统和 RAID 元数据,无法恢复。

前置条件:本文所有写测试都只写到文件系统里的一个测试目录。对设备只允许做读测试,并且命令里必须带 --readonly,这是 fio 提供的保险,加上它之后 fio 不会对设备做任何写入。设备名用型号和序列号核对,不要凭 /dev/sdX 的字母判断。

怎么回退:写错了无法回退,只能从备份恢复。所以不要复制别处的 fio 命令来跑,尤其是带 --filename=/dev/... 的。

第一层:网络,用 iperf3 ​

iperf3 在两台机器之间发送数据,测量纯网络吞吐,不涉及磁盘和 SMB。

在 NAS 上启动服务端 ​

方式一:用插件。 omv-extras 的 openmediavault-iperf3 插件在 服务 → iPerf3(Services → iPerf3)下有一个设置(Settings)页,勾选 Enable 并保存,点击应用,NAS 就作为 iperf3 服务端运行,默认端口是 5201。用完记得取消勾选。这个插件没有官方中文译名,字段以界面显示为准。插件的 Schedule 页还能让 NAS 定时作为客户端去测另一台机器,输出追加到 /var/log/omv-iperf3-jobs.log。插件概况见 小工具合集。

方式二:临时用命令。 在 OMV 的 shell 里:

sh
apt-get install iperf3
iperf3 -s

测完按 Ctrl+C 停止。如果安装时询问是否把 iperf3 作为守护进程自动启动,选「否」。

两种方式都要保证 TCP 5201 端口没有被 OMV 的防火墙(网络 → 防火墙,Network → Firewall)拦住。

在客户端电脑上测试 ​

客户端同样要安装 iperf3,版本不必完全一致。在客户端电脑上:

sh
iperf3 -c <NAS 的 IP>             # 客户端发送,NAS 接收(测上传方向)
iperf3 -c <NAS 的 IP> -R          # 反向,NAS 发送,客户端接收(测下载方向)
iperf3 -c <NAS 的 IP> -P 4        # 4 个并行连接

两个方向都要测。其他常用参数:-t <秒> 设置测试时长(默认 10 秒),--bidir 同时双向测试,-J 输出 JSON。UDP 测试用 -u,带宽默认只有 1 Mbit/s,需要用 -b 指定,例如 -b 0 表示不限速。

怎么读结果 ​

text
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  <数据量>     <速率>          <重传次数>   sender
[  5]   0.00-10.00  sec  <数据量>     <速率>                       receiver

上面只是输出的格式,数值要看你自己的测试结果。看三件事:

  • Bitrate 是否接近链路的理论上限。按标准 1500 字节 MTU 推算,千兆网络的 TCP 吞吐上限约 940 Mbit/s(约 117 MB/s),2.5G 约 2.35 Gbit/s,10G 约 9.4 Gbit/s,实测略低一点是正常的。
  • Retr(重传次数)持续偏大,说明丢包,先查网线、交换机端口和网卡。
  • 单个连接达不到、-P 4 却能接近上限,说明单连接受 CPU 或延迟限制。

第二层:磁盘,用 fio ​

fio 是通用的 I/O 测试工具,可以控制读写方式、块大小和并发。它不是 OMV 自带的,用 Debian 软件源里的版本,测完可以卸载:

sh
apt-get install fio

准备测试目录 ​

在要测试的数据文件系统上建一个测试目录,并确认剩余空间足够。挂载点形如 /srv/dev-disk-by-uuid-<UUID>,可以这样查看:

sh
findmnt -o TARGET,SOURCE,FSTYPE,AVAIL | grep /srv/
sh
TESTDIR=/srv/dev-disk-by-uuid-<UUID>/fio-test
mkdir -p "$TESTDIR"

不要在系统盘上测:系统盘很小,而且测试会影响整个系统。

三个基本测试 ​

顺序写(大文件上传、备份写入的场景):

sh
fio --name=seq-write --directory="$TESTDIR" --rw=write --bs=1M --size=4G \
    --ioengine=libaio --iodepth=8 --direct=1

顺序读(大文件下载、媒体播放的场景):

sh
fio --name=seq-read --directory="$TESTDIR" --rw=read --bs=1M --size=4G \
    --ioengine=libaio --iodepth=8 --direct=1

随机读写(小文件、数据库、虚拟机磁盘的场景),70% 读 30% 写,跑 60 秒:

sh
fio --name=rand-rw --directory="$TESTDIR" --rw=randrw --rwmixread=70 --bs=4k --size=1G \
    --ioengine=libaio --iodepth=32 --direct=1 --runtime=60 --time_based --group_reporting

参数的含义:

参数含义
--directory测试文件放的目录,fio 会在里面创建以任务名命名的文件
--rwread、write 是顺序读写,randread、randwrite、randrw 是随机读写
--bs每次读写的块大小,大块(1M)测吞吐,小块(4k)测每秒操作数
--size测试文件大小,必须小于剩余空间
--direct=1绕过内存缓存,直接读写磁盘,否则测到的是内存的速度
--iodepth同时排队的请求数,机械盘用小一点,固态盘可以更大
--runtime、--time_based限定运行时间,不管文件是否读写完

怎么读结果 ​

fio 的输出很长,先看这几处:

  • BW=:带宽,同时给出 MiB/s 和 MB/s,顺序测试看它。
  • IOPS=:每秒完成的操作数,随机测试看它。
  • clat 与 99.00th:完成延迟的平均值和 99 分位,后者代表偶发的长延迟,机械盘和 SMR 盘上这个值会很难看。
  • 最后一行的 util=:磁盘利用率,接近 100% 说明磁盘已经跑满。

单块磁盘的只读测试 ​

要比较 RAID、SnapRAID 或 mergerfs 里每块盘的速度,找出慢盘,可以对设备做只读测试。命令里的 --readonly 不能省:

sh
lsblk -o NAME,SIZE,MODEL,SERIAL       # 先按型号和序列号确认目标盘
fio --readonly --name=disk-read --filename=/dev/<磁盘> --rw=read --bs=1M \
    --ioengine=libaio --iodepth=8 --direct=1 --runtime=30 --time_based

不要对已经挂载并且正在被使用的盘做长时间测试,会和正常访问争抢。

清理 ​

fio 创建的文件名是 <任务名>.<序号>.<序号>。先确认目录里只有测试文件,再删除,最后用只能删除空目录的 rmdir:

sh
ls -l "$TESTDIR"
rm -- "$TESTDIR"/seq-write.0.0 "$TESTDIR"/seq-read.0.0 "$TESTDIR"/rand-rw.0.0
rmdir "$TESTDIR"

关于 dd ​

网上常见 dd if=/dev/zero of=测试文件 bs=1M count=… 的测速法,结果不可靠:默认会写进内存缓存,测到的是内存速度;全零数据在启用了压缩的 Btrfs 或 ZFS 上会被压缩成几乎没有。必须用 dd 时,至少加上 oflag=direct 或 conv=fdatasync。

第三层:端到端 ​

上面两层测的是「部件」,端到端测的是「整条链路」:在客户端电脑上,通过 SMB 共享复制一个 4 GiB 以上的大文件,上传和下载各一次,再复制一个包含几千个小文件的文件夹。

  • 用系统自带的速度显示,或者命令行里用 time 计时,再用「文件大小除以用时」算出速度。
  • 每次测试换一个文件,避免客户端缓存让第二次的结果虚高。
  • 传输时在 NAS 上运行 top:smbd 占满一个核,说明受 CPU 或协议限制;wa 偏高,说明受磁盘限制。也可以在 诊断 → 性能统计(Diagnostics → Performance Statistics)里看网络和 CPU 曲线;磁盘 I/O 曲线需要安装官方插件 openmediavault-diskstats。

判断瓶颈 ​

把三层的结果并排放在一起,最低的那一层就是瓶颈:

网络磁盘端到端结论
接近上限很快很慢问题在 SMB、CPU、客户端或小文件,见 SMB 传输性能调优
接近上限慢慢,和磁盘接近磁盘是瓶颈,检查是否 SMR 盘、RAID 写入惩罚、后台任务
低于上限很快慢,和网络接近网络是瓶颈,检查网线、协商速率、交换机
三项都正常三项都正常仍然慢客户端的问题,换设备对比

检查结果 ​

把测试结果记下来,方便以后对比:

日期测试项命令结果备注
iperf3 上传iperf3 -c <IP>
iperf3 下载iperf3 -c <IP> -R
fio 顺序写见上
fio 顺序读见上
fio 随机读写见上
SMB 复制大文件

测试结束后确认:测试文件已清理,临时开启的 iperf3 服务已停止,不再需要的 fio 可以用 apt-get remove fio 卸载。

常见问题 ​

fio 报 No such file or directory 或 Permission denied。 测试目录不存在,或者你不是 root。

fio 报 libaio 相关的错误。 改用 --ioengine=psync(同步 I/O),--iodepth 对它不起作用。

顺序读测出来的速度比网络上限高很多。 数据被缓存了。确认带了 --direct=1,并增大 --size。

用 ZFS 或 tmpfs 测试,--direct=1 报错或结果异常。 并非所有文件系统都支持绕过缓存。这种情况下用更大的 --size,并加上 --end_fsync=1。

参考资料 ​

OpenMediaVault 非官方中文使用指南,与 openmediavault 项目及其开发者无隶属关系。