​​Linux开源存储漫谈(5)SPDK iSCSI Target初体验

本文详细介绍了如何配置和测试SPDKiSCSITarget的性能,包括开启iommu、卸载NVMe驱动、初始化SPDK环境、运行iscsi_tgt服务以及使用rpc.py配置目标节点。通过对比Linux-IOiSCSITarget和NFS的测试数据,展示了SPDK在读写速度和IOPS上的显著优势,尤其是在混合随机读写场景下。
摘要由CSDN通过智能技术生成

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-RPCiSCSI基本概念

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 iSCSISPDK iSCSI Target
iops728k299k282k

Bandwidth

2842MiB1183MiB1101MiB
Latency338 usec839 usec445.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/_completenumjobs

iops(read)

lio/spdk

bw(read)

lio/spdk

iops(write)

lio/spdk

bw(write)

lio/spdk

64/16/16/161629.4k/38.8k115MiB/151MiB7355/969628.7MiB/37.9MiB
32/8/8/81629.8k/39.0k117MiB/153MiB7464/977029.2MiB/38.2MiB
32/8/8/8828.9k/41.0k113MiB/160MiB7229/10.3k28.2MiB/40.2MiB

结合顺序读及随机读写数据、host、qemu虚拟机资源消耗数据,尤其是混合随机读写场景,spdk iSCSI Target性能明显优于Linux-IO iSCSI target,读写吞吐和iops都有30%的提升

 

欢迎转载,请注明出处

 

SPDK存储性能开发套件)官方文档中文版。 第一章 简介 1 1.1.什么是SPDK? 1 1.2.入门 1 1.3. Vagrant开发环境 3 1.4.更新日志(略) 6 第二章 概念 6 2.1. 用户空间驱动程序** 6 2.2. 来自用户空间的DMA** 7 2.3. 消息传递和并发** 9 2.4. NAND Flash SSD内部 13 2.5. 将I / O提交到NVMe设备** 15 2.5.1 NVMe规范 15 2.5.2 SPDK NVMe驱动程序I / O路径 15 2.6. 使用Vhost-user进行虚拟化I / O. 16 2.6.1 介绍 16 2.6.2 QEMU 17 2.6.3 设备初始化 18 2.6.4 I / O路径 19 2.6.5 SPDK优化 20 2.7. SPDK目录结构概述 20 2.8. SPDK移植指南 22 第三章 用户指南 22 3.1. 系统配置用户指南 22 3.1.1 IOMMU配置 22 3.2. SPDK应用程序概述 23 3.2.1 配置SPDK应用程序 23 3.3. iSCSI Target 26 3.3.1. iSCSI Target入门指南 26 3.3.2. 通过配置文件配置iSCSI Target 27 3.3.3. 通过RPC方法配置iSCSI Target 28 3.3.4. 配置iSCSI启动器 29 3.3.5. rpc配置示例*** 30 3.3.6. iSCSI 热插拔 32 3.4. NVMe over Fabrics Target 32 3.5. Vhost Target(略) 37 3.6 块设备用户指南 38 3.6.1 bdev介绍 38 3.6.2 通用RPC命令 38 3.6.3 Ceph RBD 39 3.6.4 压缩虚拟Bdev模块 40 3.6.5 加密虚拟Bdev模块 41 3.6.6 延迟vbdev模块 41 3.6.7 GPT(GUID分区表) 42 3.6.8 iSCSI bdev 43 3.6.9 Linux AIO bdev 43 3.6.10 OCF虚拟bdev 43 3.6.11 Malloc bdev 44 3.6.12 NULL bdev 44 3.6.13 NVMe bdev 44 3.6.14 逻辑卷Lvol 45 3.6.15 RAID 46 3.6.16 Passthru 46 3.6.17 Pmem 46 3.6.18 Virtio Block 47 3.6.19 Virtio SCSI 47 3.7 BlobFS(Blobstore文件系统) 48 3.7.1 RocksDB集成 48 3.7.2 FUSE插件 49 3.8 JSON-RPC方法(略) 49 第四章 程序员指南 49 4.1. Blobstore程序员指南 49 4.1.1 介绍 50 4.1.2 运作理论 50 4.1.3 设计注意事项 52 4.1.4 例子 54 4.1.5配置 54 4.1.6 组件细节 54 4.2. 块设备层编程指南 56 4.3 编写自定义块设备模块 58 4.3.1 介绍 58 4.3.2 创建一个新模块 59 4.3.3创建虚拟Bdev 60 4.4 NVMe over Fabrics目标编程指南 61 4.4.1 介绍 61 4.4.2 原语结构体 61 4.4.3 基础函数 62 4.4.4访问控制 62 4.4.5发现子系统 62 4.4.6 传输 63 4.4.7选择线程模型 63 4.4.8 跨CPU核心扩展 63 4.4.9 零拷贝支持 63 4.4.10 RDMA 63 4.5 Flash传输层 64 4.5.1 术语 64 4.5.2 使用方法 67 4.6 GDB宏用户指南 69 4.6.1 介绍 69 4.6.2 加载gdb宏 71 4.6.3 使用gdb数据目录 72 4.6.4 使用.gdbinit加载宏 72 4.6.5 为什么我们需要显式调用spdk_load_macros 72 4.6.6 以上可用的宏总结 73 4.6.7 添加新宏 73 4.7 SPDK “Reduce”块压缩算法 73 4.7.1 介绍 73 4.7.2 例子 74 4.8 通知库 78 第五章 基本信息 79 5.1 事件框架 79 5.1.1 事件框架设计注意事项 80 5.1.2 SPDK事件框架组件 80 5.1.3 应用框架 80 5.2 逻辑卷 81 5.2.1 术语 81 5.2.2 配置逻辑卷 84 5.3 矢量数据包处理(略) 86 第六章 杂项 86 6.1 介绍 86 6.2 NVMe的P2P API 86 6.3 确定设备支持 87 6.4 P2P问题 87 第七章 驱动程序 88 7.1 NVMe驱动程序*** 88 7.1.1 介绍 88 7.1.2 例子 88 7.1.3 公共接口 89 7.1.4 NVMe驱动程序设计 89 7.1.5 NVMe over Fabrics主机支持 91 7.1.6 NVMe多进程 91 7.1.7 NVMe Hotplug 92 7.2 I/OAT驱动程序 93 7.2.1 公共接口 93 7.2.2 关键功能 93 7.3 Virtio驱动程序 93 7.3.1 介绍 93 7.3.2 2MB大页面 93 第八章 工具 94 8.1 SPDK CLI 94 8.1.1 安装所需的依赖项 94 8.1.2 运行SPDK应用程序实例 94 8.1.3 运行SPDK CLI 94 8.1.4 可选 - 创建Python虚拟环境 94 8.2 nvme-CLI 95 8.2.1 nvme-cli with SPDK入门指南 95 8.2.2 使用场景 95 第九章 性能测试报告(略) 96 第十章NVMe-oF Target跟踪点*** 96 10.1 介绍 96 10.2 启用跟踪点 97 10.3 捕获事件的快照 97 10.4 捕获足够的跟踪事件 98 10.5 添加新的跟踪点 99
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值