SPDK及环境准备篇分别介绍了SPDK及我本地的环境信息,本篇将基于我的测试环境配置SPDK iSCSI Target并测试其性能,并对比Linux-IO iSCSI Target vs NFS的测试数据,展示SPDK的性能提升
SPDK运行环境配置
环境准备篇中我们曾提及Ubuntu 22.04中如何开启iommu,这是进行SPDK iSCSI Target测试的前提,在这个过程中我个人就被折磨了很久,/sys/kernel/iommu_groups/目录下就是空空如也,网上google了很久也没能解决,再次强调一下,CLEAN的环境会少很多坑,环境准备篇中相关内容如下:
2. 修改Linux启动参数启用iommu
修改/etc/default/grub文件GRUB_CMDLINE_LINUX行,然后执行grub-mkconfig后重启操作系统,使修改生效。
root@nvme:~# cat /etc/default/grub | grep "^GRUB_CMDLINE_LINUX="
GRUB_CMDLINE_LINUX="quiet intel_iommu=on"
root@nvme:~#
root@nvme:~# grub-mkconfig -o /boot/grub/grub.cfg
通过如下命令检查iommu,注意,开启iommu后/sys/kernel/iommu_groups目录是不为空
root@nvme:~# dmesg | grep "DMAR: Intel"
[ 1.493774] DMAR: Intel(R) Virtualization Technology for Directed I/O
root@nvme:~# ls /sys/kernel/iommu_groups/
0 1 2 3 4 5 6 7 8
root@nvme:~#
第一步,先找到NVMe设备PCI信息
root@nvme:~# lspci
00:00.0 Host bridge: Intel Corporation Comet Lake-S 6c Host Bridge/DRAM Controller (rev 03)
......
01:00.1 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] Caicos HDMI Audio [Radeon HD 6450 / 7450/8450/8490 OEM / R5 230/235/235X OEM]
02:00.0 Non-Volatile memory controller: Kingston Technology Company, Inc. Device 5017 (rev 03)
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 16)
04:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
root@nvme:~#
02:00.0 Non-Volatile memory controller: Kingston就是NVMe SSD盘的PCI信息,但是,这还不够,SPDK帮助文档中通篇都是"0000:01:00.0"的PCI地址信息,但是并没有写明如何在主机获取相关信息,0000:01:00.0(域:总线:设备.功能,更多PCI信息见:Linux PCI设备驱动),lspci默认是不显示Domain信息,加-D参数运行lspci,获取精准PCI设备地址
root@nvme:~# lspci -D -s 02:00.0
0000:02:00.0 Non-Volatile memory controller: Kingston Technology Company, Inc. Device 5017 (rev 03)
root@nvme:~#
第二步,unbind内核NVMe驱动
root@nvme:~# cd /sys/bus/pci/devices/0000:02:00.0/driver
root@nvme:/sys/bus/pci/devices/0000:02:00.0/driver# echo 0000:02:00.0 > unbind
# 查看内核块设备,/dev/nvme0n1在内核中被unbind
root@nvme:/sys/bus/pci/devices/0000:02:00.0/driver# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 63.3M 1 loop /snap/core20/1879
loop1 7:1 0 53.2M 1 loop /snap/snapd/19122
loop2 7:2 0 53.2M 1 loop /snap/snapd/18933
loop3 7:3 0 111.9M 1 loop /snap/lxd/24322
loop4 7:4 0 63.3M 1 loop /snap/core20/1852
sda 8:0 0 1.8T 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 200G 0 part /
├─sda3 8:3 0 200G 0 part /data
├─sda4 8:4 0 1.4T 0 part
└─sda5 8:5 0 1007K 0 part
root@nvme:/sys/bus/pci/devices/0000:02:00.0/driver#
第三步,初始化SPDK运行环境
root@nvme:~# cd /data/github/spdk
root@nvme:/data/github/spdk# HUGEMEM=8192 ./scripts/setup.sh
0000:02:00.0 (2646 5017): nvme -> vfio-pci
root@nvme:/data/github/spdk# cat /proc/meminfo | grep -i huge
......
HugePages_Total: 4096
HugePages_Free: 4096
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 8388608 kB
root@nvme:/data/github/spdk#
可以读一下setup.sh脚本,"HUGEMEM=8192 ./scripts/setup.sh"等于"HUGEMEM=8192 ./scripts/setup.sh config",主要用来分配大页内存,遍历并绑定PCIe设备(已经从内核unbind)
第四步,运行iscsi_tgt启动SPDK自带iscsi target服务程序
# 建议新开一个窗口
root@nvme:~# cd /data/github/spdk
root@nvme:/data/github/spdk#
root@nvme:/data/github/spdk# ./build/bin/iscsi_tgt
[2023-05-17 06:31:30.664654] Starting SPDK v23.05-pre / DPDK 22.11.1 initialization...
[2023-05-17 06:31:30.664806] [ DPDK EAL parameters: iscsi --no-shconf -c 0x1 --huge-unlink --log-level=lib.eal:6 --log-level=lib.cryptodev:5 --log-level=user1:6 --iova-mode=pa --base-virtaddr=0x200000000000 --match-allocations --file-prefix=spdk_pid1576 ]
......
第五步,在启动一个新的窗口,调用rpc.py配置iscsi target
root@nvme:/data/github/spdk# ./scripts/rpc.py bdev_nvme_attach_controller -b mnvme0 -t PCIe -a 0000:02:00.0
mnvme0n1
root@nvme:/data/github/spdk# ./scripts/rpc.py iscsi_create_portal_group 1 192.168.2.111:3260
root@nvme:/data/github/spdk# ./scripts/rpc.py iscsi_create_auth_group -c 'user:disUser secret:disUserPwd muser:mDisUser msecret:mDisUserPwd' 0
root@nvme:/data/github/spdk# ./scripts/rpc.py iscsi_create_auth_group -c 'user:rwClientUser secret:rwClientUserPwd muser:mRwClientUser msecret:mRwClientUserPwd' 2
root@nvme:/data/github/spdk# ./scripts/rpc.py iscsi_create_initiator_group 2 ANY 192.168.2.0/24
root@nvme:/data/github/spdk# ./scripts/rpc.py iscsi_set_discovery_auth -m -r -g 0
root@nvme:/data/github/spdk# ./scripts/rpc.py iscsi_create_target_node mnvmedisk1 "my nvme disk1" "mnvme0n1:0" 1:2 64 -g 2 -r -m
root@nvme:/data/github/spdk#
JSON-RPC说明,详见:SPDK JSON-RPC
bdev_nvme_attach_controller,创建一个基于的bdev
iscsi_create_portal_group,初始化iSCSI Portal Group信息,具体参见JSON-RPC及iSCSI基本概念
iscsi_create_auth_group,两次调用分别创建iSCSI discovery auth,及Initiator的ACL auth
iscsi_create_initiator_group,配置iSCSI Initiator信息,同Linux-IO iSCSI Target
iscsi_set_discovery_auth,设置discovery 使用tag为0的auth_group
iscsi_create_target_node,创建node,参数见JSON-RPC
第六步,参考环境准备篇启动qemu虚拟机
# 不要忘了启动虚拟机前初始化tap设备
root@nvme:~# tunctl -t tap1
root@nvme:~# brctl addif kvmbr0 tap1
root@nvme:~# ifconfig tap1 up
# 启动虚拟机
root@nvme:~# cd /data/kvm/
root@nvme:/data/kvm# ./start-kvm.iscsi.sh
第七步,进入虚拟机,运行iscsiadm(initiator配置见: 配置iSCSI Initiator)
root@vm-nvme:~# iscsiadm -m discovery -t sendtargets -p 192.168.2.111:3260
192.168.2.111:3260,1 iqn.2016-06.io.spdk:mnvmedisk1
root@vm-nvme:~# iscsiadm -m node -T iqn.2016-06.io.spdk:mnvmedisk1 --login
Logging in to [iface: default, target: iqn.2016-06.io.spdk:mnvmedisk1, portal: 192.168.2.111,3260]
Login to [iface: default, target: iqn.2016-06.io.spdk:mnvmedisk1, portal: 192.168.2.111,3260] successful.
root@vm-nvme:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
fd0 2:0 1 4K 0 disk
loop0 7:0 0 63.3M 1 loop /snap/core20/1852
loop1 7:1 0 63.3M 1 loop /snap/core20/1879
loop2 7:2 0 111.9M 1 loop /snap/lxd/24322
loop3 7:3 0 53.2M 1 loop /snap/snapd/18933
loop4 7:4 0 53.2M 1 loop /snap/snapd/19122
sda 8:0 0 100G 0 disk
sdb 8:16 0 32.2G 0 disk
├─sdb1 8:17 0 32.1G 0 part /
├─sdb14 8:30 0 4M 0 part
└─sdb15 8:31 0 106M 0 part /boot/efi
vda 252:0 0 366K 0 disk
root@vm-nvme:~#
fio测试SPDK iSCSI Target
对比内核NVMe测试数据,内核Linux-IO iSCSI Target及SPDK iSCSI Target,顺序读数据如下表
内核NVMe | 内核Linux-IO iSCSI | SPDK iSCSI Target | |
iops | 728k | 299k | 282k |
Bandwidth | 2842MiB | 1183MiB | 1101MiB |
Latency | 338 usec | 839 usec | 445.15 usec |
混合随机读写测试
[global]
bs=4096
rw=write
ioengine=libaio
size=50G
direct=1
iodepth=256
iodepth_batch=64
iodepth_low=64
iodepth_batch_complete=64
userspace_reap
group_reporting
[test]
numjobs=1
filename=/dev/sdc
iodepth/_low/_batch/_complete | numjobs | iops(read) lio/spdk | bw(read) lio/spdk | iops(write) lio/spdk | bw(write) lio/spdk |
64/16/16/16 | 16 | 29.4k/38.8k | 115MiB/151MiB | 7355/9696 | 28.7MiB/37.9MiB |
32/8/8/8 | 16 | 29.8k/39.0k | 117MiB/153MiB | 7464/9770 | 29.2MiB/38.2MiB |
32/8/8/8 | 8 | 28.9k/41.0k | 113MiB/160MiB | 7229/10.3k | 28.2MiB/40.2MiB |
结合顺序读及随机读写数据、host、qemu虚拟机资源消耗数据,尤其是混合随机读写场景,spdk iSCSI Target性能明显优于Linux-IO iSCSI target,读写吞吐和iops都有30%的提升
欢迎转载,请注明出处