SPDK 是 Intel 发布的存储性能开发工具集,旨在帮助存储 OEM 和 ISV 整合硬件,提升存储系统性能与效率。随着固态存储设备优势凸显,存储软件栈性能愈发关键,SPDK 应运而生。其工作依赖运行于用户态和轮询模式两大关键技术,前者避免内核上下文切换和中断以节省处理开销,后者改变 I/O 基本模型,避免中断延迟和开销。SPDK 由硬件驱动、后端块设备、存储服务、存储协议等数个子组件构成,各组件既能构建端对端体系结构,也可融入非 SPDK 架构。文章还介绍了 SPDK 的编译使用步骤及实现原理,并指出其适用场景。此外,阐述了 SPDK 的动机、基本原理,以及在 Ceph 中的使用情况,同时介绍了 Blobstore 和 BlobFS 的设计目标、工作方式及与 SPDK 的关系,还对比了与 GAE 相关的 3 种存储方法。重要亮点
SPDK 诞生背景与目标:固态存储设备在性能、功耗和机架密度上优势显著,取代传统磁盘设备趋势明显。但存储软件栈性能成为瓶颈,为助存储相关企业整合硬件,Intel 构建 SPDK,通过运用 Intel 多项技术,提升存储系统效率与性能,如借助硬件设计软件,实现每秒数百万次 I/O 读取。
SPDK 关键技术:一是运行于用户态,设备驱动代码不在内核运行,避免内核上下文切换和中断,节省处理开销,让更多时钟周期用于实际数据存储,无论存储算法复杂与否,都能提升性能和降低延迟;二是轮询模式,应用程序提交读写请求后继续执行其他工作,定时检查 I/O 是否完成,避免中断开销,在固态设备时代,对提升 I/O 效率效果显著,可降低延迟、提高吞吐量。
SPDK 组件构成:硬件驱动包含 NVMe Driver 和 Inter QuickData Technology 等;后端块设备有 NVMe over Fabrics initiator、Ceph RADOS Block Device 等多种;存储服务包括 Block device abstration layer 和 Blobstore;存储协议涵盖 iSCSI target、NVMe-oF target 等。从流程看,由网络前端、处理框架和存储后端组成,各部分协同工作,且部分组件可独立用于加速其他软件。
SPDK 适用场景判断:判断 SPDK 组件是否适合自身体系结构,可从多方面考量。如存储系统基于 Linux 或 FreeBSD,且硬件平台为 Intel 体系结构;高性能路径运行在用户态,系统能合并无锁的 PMDs 到线程模型;当前使用 DPDK 处理网络数据包工作负载,且开发团队具备理解和解决问题的专业技能等场景较为适用。
下载代码:
1 | git clone https://github.com/spdk/spdk --recursive |
1 | cd spdk |
1 | #使用fio测试 |
绑定设备
data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">1.需要解绑设备,并格式化;相当于准备一块未格式化的nvme盘
1 | 执行前 |
查看状态
1 | root@spdk:~/github/spdk# /root/github/spdk/scripts/setup.sh status |
1 | 查找traddr(参考 https://www.jianshu.com/p/eeaf81ffb7b5) |
fio配置
1 | root@spdk:~/github/spdk# cat /root/github/spdk/examples/nvme/fio_plugin/example_config.fio |
问题
提示:INFO:Requested 1024 hugepages but 8192 already allocated
root user memlock limit: 8MB
This is the maxinum amount of memory you will be
able to use whit DPDK and VFIO if run as user root
To change this, please adjust limits.conf memlock limit for user root;
查看一下文章中的内容;
SPDK 存储性能开发套件
SPDK.liblightnvm 提供了一个使用 英特尔存储性能开发套件(Intel SPDK) 实现的内核绕过后端。
安装 SPDK
在最新的Ubuntu长期支持版系统上,运行以下命令从源码安装SPDK:
Make sure system is up to date
sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade
Clone SPDK into /opt/spdk
sudo git clone https://github.com/spdk/spdk /opt/spdk
sudo chown -R $USER:$USER /opt/spdk
Go to the repository
cd /opt/spdk
Checkout the v18.07 release
git checkout v18.07
git submodule update –init
Install dependencies
sudo ./scripts/pkgdep.sh
sudo apt-get install uuid-dev
Configure and build it
./configure
make -j $(nproc)
Check that it works
./test/unit/unittest.sh
Install DPDK
cd /opt/spdk/dpdk
sudo make install
Install SPDK
cd /opt/spdk
sudo make install
上一个 unittest.sh 命令的输出应该为:
=====================
All unit tests passed
解除设备绑定并设置内存
通过运行以下命令,将配置大页并使设备从内核NVMe驱动程序分离:
sudo HUGEMEM=8192 /opt/spdk/scripts/setup.sh
这应该输出类似内容:
0000:01:00.0 (1d1d 2807): nvme -> vfio-pci
如果上述内容是从setup.sh输出的其他内容,例如:
0000:01:00.0 (1d1d 2807): nvme -> uio_generic
Or: 或者:
Current user memlock limit: 16 MB
This is the maximum amount of memory you will be
able to use with DPDK and VFIO if run as current user.
To change this, please adjust limits.conf memlock limit for current user.
WARNING: memlock limit is less than 64MB
DPDK with VFIO may not be able to initialize if run as current user.
然后查阅关于无限制启用“VFIO”的说明。
重新绑定设备
运行以下命令:
sudo /opt/spdk/scripts/setup.sh reset
输出内容应类似于:
0000:01:00.0 (1d1d 2807): vfio-pci -> nvme
设备标识符
由于设备在 /dev 中不再可用,因此将使用 SPDK 表示法来表示PCI ID,例如 traddr:0000:01:00.0,例如使用命令行界面:
sudo nvm_dev info traddr:0000:01:00.0
并且使用API的话,情况会类似如下:
…
struct nvm_dev *dev = nvm_dev_open(“traddr:0000:01:00.0”);
…
构建支持SPDK的liblightnvm
有了SPDK后,使用以下命令配置liblightnvm的构建:
make spdk_on configure build
将您的源文件与liblightnvm和SPDK相链接
Invoke like so: 调用方式如下:
gcc hello.c -o hello
-fopenmp
-llightnvm
-lspdk_nvme
-lspdk_util
-lspdk_log
-lspdk_env_dpdk
-lrte_bus_pci
-lrte_eal
-lrte_mempool
-lrte_mempool_ring
-lrte_pci
-lrte_ring
-lrt
-ldl
-lnuma
-luuid
上述内容编译了快速入门指南中的示例,请注意,代码中有一个硬编码的设备标识符,你必须更改此标识符以匹配 SPDK 标识符。
无限制启用VFIO
如果nvme重新绑定到uio_generic而不是vfio,那么VT-d可能不受支持或已禁用。无论哪种情况,尝试以下两个步骤:
验证您的CPU支持VT-d且已在BIOS中启用。
通过提供内核选项来启用内核。如果你使用的不是英特尔CPU,请查阅关于为你的CPU启用VT-d/IOMMU的文档。
增加限制,打开/etc/security/limits.conf并添加:
- soft memlock unlimited
- hard memlock unlimited
root soft memlock unlimited
root hard memlock unlimited
完成这些步骤后,执行以下命令:
dmesg | grep -e DMAR -e IOMMU
应包含:
[ 0.000000] DMAR: IOMMU enabled
并且这条这条命令:
find /sys/kernel/iommu_groups/ -type l
输出应类似于:
/sys/kernel/iommu_groups/7/devices/0000:00:1c.5
/sys/kernel/iommu_groups/5/devices/0000:00:17.0
/sys/kernel/iommu_groups/3/devices/0000:00:14.2
/sys/kernel/iommu_groups/3/devices/0000:00:14.0
/sys/kernel/iommu_groups/11/devices/0000:03:00.0
/sys/kernel/iommu_groups/1/devices/0000:00:01.0
/sys/kernel/iommu_groups/1/devices/0000:01:00.0
/sys/kernel/iommu_groups/8/devices/0000:00:1d.0
/sys/kernel/iommu_groups/6/devices/0000:00:1c.0
/sys/kernel/iommu_groups/4/devices/0000:00:16.0
/sys/kernel/iommu_groups/2/devices/0000:00:02.0
/sys/kernel/iommu_groups/10/devices/0000:00:1f.6
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/9/devices/0000:00:1f.2
/sys/kernel/iommu_groups/9/devices/0000:00:1f.0
/sys/kernel/iommu_groups/9/devices/0000:00:1f.4
And SPDK setup: 以及SPDK设置:
sudo HUGEMEM=8192 /opt/spdk/scripts/setup.sh
Should rebind the device to vfio-pci, eg.:应将设备重新绑定到 vfio-pci,例如:
0000:01:00.0 (1d1d 2807): nvme -> vfio-pci
HUGEPAGES检查并手动更改 可用内存,也称为
安装脚本提供了环境变量,以通过[未提及具体方式]来控制可用内存量。但是,如果你想手动更改或只是查看配置,请参考以下内容。
通过运行以下命令检查系统配置:
grep . /sys/devices/system/node/node0/hugepages/hugepages-2048kB/*
如果你尚未运行设置脚本,那么它很可能输出:
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:0
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:0
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0
运行设置脚本后,它应该输出:
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:1024
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:1024
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0
这表明有大小为 的大页可用,也就是说,总共可以使用2GB。
增加可用于的内存的一种方法是增加大页的数量。例如,通过将增加到 ,将内存从2GB增加到8GB:
echo “4096” > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
完成此操作后,检查配置应输出:
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:4096
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:4096
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0