外观
性能测试: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 会在里面创建以任务名命名的文件 |
--rw | read、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。
参考资料
- fio 官方文档
- iperf3 官方文档
- omv-extras 的 iPerf3 插件源码:openmediavault-iperf3