一、概述
在SPDK环境下使用FIO进行存储性能测试,必须从源码编译并集成SPDK引擎插件(fio_plugin)。FIO源码需置于SPDK预设路径(如/usr/src/fio),并通过SPDK configure脚本启用--with-fio参数完成联合构建。运行时须通过LD_PRELOAD或LD_LIBRARY_PATH显式加载libspdk_nvme.so等插件库,并确保目标NVMe设备已由SPDK setup.sh解绑内核驱动、绑定至vfio-pci/uio_pci_generic。FIO配置文件中ioengine必须设为spdk,filename字段需传入SPDK设备连接字符串(如trtypePCIe traddr0000:01:00.0 ns1),而非普通文件路径。整个流程高度依赖路径一致性、环境变量配置及root权限与大页内存准备。
本文使用的Fio源码版本是:fio-3.38;SPDK版本是SPDK_V22.09。
如果要测试P2P的功能,请事先检查系统是否支持。
grep CONFIG_PCI_P2PDMA /boot/config-*********安装Fio或SPDK时,提示需要安装各类“插件/依赖”,尤其是SPDK,在安装的时候会有直接提示,本文暂不概述安装细节,相关安装包/安装补丁请查看附件资源。
二、安装Fio
cd fio_dir ./configure make&&make install三、安装SPDK
编译SPDK,启用fio插件 cd /path/to/spdk ./configure --with-fio=/usr/src/fio [其他参数,如 --with-rdma] 编译SPDK。这将会同时编译SPDK库、工具以及fio_plugin。 make -j 编译完成后,关键的插件库文件是 build/fio/spdk_nvme,动态库为 libspdk_nvme.so 或类似名称。./configure --with-fio=/path/to/fio # 指定你的 FIO 源码路径,编译成功后,build/lib 目录才会生成 libspdk_fio.so 文件。
四、系统配置(主要用于P2P测试)
为 SPDK 搭建一个“无内核干扰、低延迟、安全的 PCIe 设备直通环境”, intel_iommu=on + iommu=pt:启用并优化 IOMMU,让 SPDK 可以通过 vfio-pci 安全地直接控制设备;pcie_acs_override:拆分 IOMMU 组,让 SPDK 可以单独绑定指定的存储设备;
1、解除用户对内存的软/硬限制
2、内核配置
开启 Intel VT-d(IOMMU 功能)
启用 I/O 内存管理单元,让系统支持 DMA 地址重映射、设备内存隔离,为后续的设备直通/用户态高性能访问做准备;支持 vfio-pci 驱动,这是 SPDK、KVM 等场景下安全访问 PCIe 设备的标准方式;
intel_iommu=onIOMMU 的“直通模式”
让内核对主机设备使用 1:1 地址映射,减少 IOMMU 转换开销,提升性能;开启后能大幅降低 I/O 延迟,避免内核层的额外开销。让内核不再“触碰”直通设备的内存地址,完全交给 vfio-pci 管理;
iommu=pt设备直通
pcie_acs_override=downstream,multifunctiondownstream:强制让内核认为 PCIe 下游端口支持 ACS,从而拆分 IOMMU 组;
multifunction:强制让内核认为多功能设备的端点支持 ACS,进一步拆分设备;
把原本共享的 IOMMU 组拆分成独立的设备组,让你可以单独把某个 NVMe/SSD 控制器交给 SPDK 绑定,而不用把整个 PCIe 控制器都直通出去。
提示:这是“软hack”式的配置,会绕过硬件原生的 ACS 隔离,有一定安全风险,但在物理机非虚拟化的 SPDK 场景下是安全的。
3、编译内核
grub2-mkconfig -o /boot/grub2/grub.cfg4、大页内存配置
SPDK 使用用户态轮询驱动,需要预先分配大量物理连续内存。
减少 TLB miss,降低延迟,普通内存页是 4KB,访问时需要频繁查页表,会造成 TLB(地址转换缓存)miss,带来延迟波动;大页内存是 2MB 甚至 1GB,单个页的覆盖范围大,TLB 缓存能命中更多地址,大幅减少地址转换开销,让 SPDK 的 I/O 延迟更稳定。避免内存被交换(swap)出去,普通内存可能会被系统交换到磁盘,导致存储 I/O 性能暴跌;大页内存是物理上连续、锁定的内存,不会被交换出去,保证 SPDK 运行时的内存访问速度稳定。
修改 /etc/sysctl.conf 后,执行 sysctl -p 即可让配置生效五、测试
1、nvme driver替换为vfio
cd /SPDK_Path/scripts ./setup.sh ./setup status如果nvme driver 转换未成功,如图所示,可能需要把nvme设备从当前绑定的内核 nvme 驱动上“解绑”下来。
2、测试脚本
一、[global] 全局配置段 ioengine=spdk spdk告诉FIO使用SPDK用户态驱动引擎,而不是默认的内核文件 I/O 引擎,直接通过SPDK访问NVMe设备。 thread=1 1 使用线程模式(而不是进程)来执行I/O 操作,减少上下文切换开销。 group_reporting=1 1 把所有测试任务的结果合并成一份报告,而不是每个任务单独输出。 direct=1 1 开启直接I/O,绕过系统页缓存,直接向设备发起读写,模拟真实的裸设备性能。 verify=0 0 关闭数据校验,只测试性能不验证数据正确性(测试吞吐量/延迟时常用) 。 time_based=1 1 按时间长度运行测试,而不是读写固定大小的数据量。 ramp_time=0 0 不设置预热时间,测试开始就直接进入稳定负载。 runtime=60 60 测试持续运行60秒。 iodepth=128 128 每个I/O队列的深度为128,用来模拟高并发请求,压满设备的队列能力。 rw=read read 测试模式为纯顺序读取(不写、不随机读)。 bs=1M 1M 单次I/O的块大小为1MB,测试大顺序块读取性能。 二、[test] 测试任务段 numjobs=4 4 启动4个并发任务(线程)来执行测试,模拟多线程访问设备的场景。 filename=trtype=PCIe traddr=0000.85.00.0 ns=1 PCIe地址这是 SPDK 引擎特有的设备指定方式: - trtype=PCIe:传输类型为 PCIe NVMe 设备 - traddr=0000.85.00.0:设备的 PCI 地址(和你之前绑定的 0000:85:00.0 对应) - ns=1:指定访问设备上的 1 号命名空间(Namespace) SPDK 模式下,必须用 trtype/traddr 这种格式直接指定 PCI 设备,因为设备已经被绑定到 vfio-pci,内核不再提供块设备节点。3、运行脚本
LD_PRELOAD=/path/to/spdk/build/fio/fio spdk_test.fio