关键词
DPDK:全称Intel Data Plane Development Kit,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持。通俗地说,就是一个用来进行包数据处理加速的软件库。
CBDMA :全称Crystal Beach DMA是一个CPU里面的DMA引擎,有了它之后就能够在不中断CPU的情况下执行高效的内存拷贝。
NVMe SSD:有一个SSD Controller,同时存储空间划分成若干个独立的逻辑空间,每个空间逻辑块地址(LBA)范围是0到N-1 (N是逻辑空间大小),这样划分出来的每一个逻辑空间我们就叫做NameSpace。
为什么产生
用户使用现在的固态设备,吞吐量和延迟性能比传统的磁盘好太多,现在总的处理时间中,存储软件占用了更大的比例。
硬件推动软件革新需求。
什么是spdk
SPDK(全称Storage Performance Development Kit),Intel发布的,提供了一整套工具和库,以实现高性能、扩展性强、全用户态的存储应用程序。它是继DPDK之后,intel在存储领域推出的又一项颠覆性技术,旨在大幅缩减存储IO栈的软件开销,从而提升存储性能,可以说它就是为了存储性能而生。
spdk的优势
相对于传统IO方式,SPDK主要运用了两项关键技术:UIO和pooling,使用SPDK的存储系统能轻松达到数百万IOPS。
首先,将设备驱动代码运行在用户态,避免内核上下文切换和中断将会节省大量的处理开销,允许更多的时钟周期被用来做实际的数据存储。无论存储算法(去冗,加密,压缩,空白块存储)多么复杂,浪费更少的时钟周期总是意味着更好的性能和时延。
其次,采用轮询模式改变了传统I/O的基本模型。在传统的I/O模型中,应用程序提交读写请求后进入睡眠状态,一旦I/O完成,中断就会将其唤醒。轮询的工作方式则不同,应用程序提交读写请求后继续执行其他工作,以一定的时间间隔回头检查I/O是否已经完成。这种方式避免了中断带来的延迟和开销,并使得应用程序提高了I/O效率。
概括:要在用户态实施一套基于用户态软件驱动的完整I/O栈。
spdk的组件构成
imageSPDK中大概有三类子组件:网络前端、处理框架、后端。
网络前端子组件:包括DPDK网卡驱动和用户态网络服务UNS(这是一个Linux内核TCP/IP协议栈的替代品,能够突破通用TCP/IP协议栈的种种性能限制瓶颈)。DPDK在网卡侧提供了一个高性能的发包收包处理框架,在数据从网卡到操作系统用户态之间提供了一条快速通道。UNS代码则继续这一部分处理,稍加处理TCP/IP数据包的标准处理方式,并形成iSCSI命令。
处理框架:包括iSCSI Target和Customer Storage App,“处理框架”部分拿到了数据包内容,将iSCSI命令转换为SCSI块级命令。然而,在它将这些命令发到“后端”驱动之前,SPDK提供了一套API框架,让厂商能够插入自己定义的处理逻辑(架构图中绿色的方框)。通过这种机制,存储厂商可在这里实现例如缓存、去重、压缩、加密、RAID计算,或擦除码(Erasure Coding)计算等功能,使这些功能包含在SPDK的处理流程中。
后端:数据到达了“后端”驱动层,在这里SPDK和物理块设备交互(读和写操作)。这一系列后端设备驱动涵盖了不同性能的存储分层,保证SPDK几乎与每种存储应用形成关联。
典型使用场景
- 提供块设备接口的后端存储应用,诸如iSCSI Target和 NVMe-oF Target;
- 对虚拟机中I/O (virtio) 的加速,主要支持Linux系统下的QEMU/KVM作为hypervisor 管理虚拟机的场景,使用vhost交互协议实现基于共享内存通道的高效vhost用户态target (例如vhost SCSI/blk/NVMe target)
- SPDK加速数据库存储引擎。通过实现了RocksDB中的抽象文件类,SPDK的blobfs/blobstore目前可以和Rocksdb集成,用于在NVMe SSD上加速实现RocksDB引擎的使用。该操作的实质是bypass kernel文件系统将完全使用基于SPDK的用户态I/O stack。
spdk例子
hello-world.c
重要概念
让我们先搞清楚两个问题:
-
问题1: 每一块NVMe固态硬盘里都一个控制器(Controller), 那么发现的所有NVMe固态硬盘(也就是NVMe Controllers)以什么方式组织在一起?
-
问题2: 每一块NVMe固态硬盘都可以划分为多个NameSpace (类似逻辑分区的概念), 那么这些NameSpace以什么方式组织在一起?
链表。
代码主要流程
spdk_env_opts_init(&opts);
spdk_env_init(&opts);
rc = spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL);
hello_world();
cleanup();
-
1-2,初始化spdk环境及其配置基本项
-
3,调用函数spdk_nvme_probe()主动发现NVMe SSDs设备。 关键函数是spdk_nvme_probe()。
-
4,调用函数hello_world()做简单的读写操作
-
5,调用函数cleanup()以释放内存资源,卸载NVMe SSD设备等。
probe_cb和attach_cb是两个callback函数, (其实还有remove_cb)
-
probe_cb: 当扫描NVMe设备后被调用
-
attach_cb: 当一个NVMe设备已经被挂接到一个用户态的NVMe 驱动的时候被调用
继续看代码:
static void
hello_world(void)
{
struct ns_entry *ns_entry;
struct hello_world_sequence sequence;
int rc;
size_t sz;
TAILQ_FOREACH(ns_entry, &g_namespaces, link) {
/*
* Allocate an I/O qpair that we can use to submit read/write requests
* to namespaces on the controller. NVMe controllers typically support
* many qpairs per controller. Any I/O qpair allocated for a controller
* can submit I/O to any namespace on that controller.
*
* The SPDK NVMe driver provides no synchronization for qpair accesses -
* the application must ensure only a single thread submits I/O to a
* qpair, and that same thread must also check for completions on that
* qpair. This enables extremely efficient I/O processing by making all
* I/O operations completely lockless.
*/
ns_entry->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ns_entry->ctrlr, NULL, 0);
if (ns_entry->qpair == NULL) {
printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n");
return;
}
……
spdk_nvme_ctrlr_alloc_io_qpair:分配一个qpair,一个是submit queue,一个是complete queue,进行读写操作。一般都是一个sq和cq对应。创建好qpair后就可以通过qpair下发IO操作了。
imagerc = spdk_nvme_ns_cmd_write(ns_entry->ns, ns_entry->qpair, sequence.buf,
0, /* LBA start */
1, /* number of LBAs */
write_complete, &sequence, 0);
spdk_nvme_ns_cmd_write:提交一个写请求到ns和qpair
static void
write_complete(void *arg, const struct spdk_nvme_cpl *completion)
{
……
rc = spdk_nvme_ns_cmd_read(ns_entry->ns, ns_entry->qpair, sequence->buf,
0, /* LBA start */
1, /* number of LBAs */
read_complete, (void *)sequence, 0);
……
}
static void
read_complete(void *arg, const struct spdk_nvme_cpl *completion)
{
struct hello_world_sequence *sequence = arg;
printf("%s", sequence->buf);
}
sdpk推荐文档:https://spdk.io/doc/
网友评论