​​Linux开源存储漫谈(4)​​存储性能软件加速库SPDK

从1991年Linux首次发行到现在的30多年时间里,存储的介质、接口、协议都演进了几个代际,存储容量和传输速率也几乎遵循摩尔定律的发展,然而,人们对高性能的追求是无止境的,从持续满足高性能的角度来看,有两种途径,一是更高性能的硬件设备,二是减少软件处理的开销,更高性能硬盘设备依赖硬件厂商的不懈努力,软件处理是指存储软件栈,即Linux Storage Stack,见图,

e1c9ce9cb6ff46c9a818c00a7dc03b2e.png

 Linux Storage Stack主要包括,VFS、Block Layer、driver等,Linux Storage Stack因为其通用性的设计为主,即不同硬件设备实现一个通用的驱动块设备驱动,不一定能够发挥共性能硬盘的优势,逐渐成为高性能存储的瓶颈。

提供软件处理性能,以整体上提高上层应用的高性能需求,SPDK就是Intel为了解决高性能访问而开发的存储性能软件加速库

SPDK

SPDK是由Intel发起的,用于加速NVMe SSD作为后端存储使用的软件加速库。SPDK并不是一个通用的适配解决方案,实现了一套基于用户态软件驱动的完整IO栈,很显然内核的文件系统如ext4、brtfs等都不能使用了,也不支持可移植操作系统接口,提供了blobfs/blobstore并使用类似于AIO的异步读写方式。

SPDK的核心是用户态、异步、轮询、无锁的NVMe驱动,并提供了零拷贝、高并发等功能。SPDK用户态驱动最大化的发挥NVMe  SSD性能优势,大幅降低NVMe command的延迟,提高单CPU核的IOps,形成高性价比的解决方案,如SPDK vhost target,以很小的性能损耗将NVMe SSD透传给qemu虚拟机,如此高性能解决方案在高性能计算中一定极受欢迎

SPDK的应用场景

SPDK比较好的应用场景包括:

1. 提供块设备接口的后端存储应用,如iSCSI Target、NVMe-OF Target

2. 对虚拟化IO加速,主要是指Linux系统下的QUME/KVM作为Hypervisor的管理虚拟化场景,使用vhost交互协议,实现基于共享内存通道的高效vhost用户态Target。如vhost iSCSI/blk/NVMe Target,从而加速虚拟机中的virtio SCSI/blk即Kernel Native NVMe协议的IO驱动,缩短了host OS中的IO栈

3. SPDK加速数据库引擎,通过实现RocksDB中的抽象文件类,SPDK的blobfs/blobstore可以和RocksDB集成,用于加速在NVMe SSD上使用RocksDB引擎,其实质是bypass kernel文件系统

SPDK NVMe驱动

Linux 内核NVMe驱动

内核态的NVMe驱动的设计以通用性为主,实现通用的块设备驱动,同时和内核其它模块深度集成,需要一些隔离的方法,比如信号量、锁、临界区等来保证操作的唯一性,这样设计有很好的兼容性和可维护性

内核驱动是如何与用户态应用程序交互呢,当内核驱动模块在被内核加载成功后,会被标识成是块设备还是字符设备,同时定义相关的访问接口,包括管理接口、数据接口等。这些接口直接或间接于文件系统子系统结合,提供给用户态的程序,通过系统调用的方式发起控制或读/写操作。

用户态应用程序和内核驱动的交互离不开用户态和内核态的上下文切换,以及系统调用的开销。参见Linux Storage Stack

 

SPDK NVMe驱动

不同于内核态NVMe驱动,SPDK NVMe驱动就是从性能的角度出发,减少软件所产生的开销,包括上下文切换、系统调用等。SPDK同时支持UIO(Userspace I/O)VFIO(Virtual Function I/O)等机制绕过内核I/O栈实现对高速NVMe SSD盘的访问和控制

UIO解决两个核心问题,其一,如何访问设备内存,Linux通过映射物理设备的内存到用户态来提供访问。其二,如何处理中断,中断本身需要在内核进行处理,UIO通过一个小的内核模块完成最基本的中断服务程序处理,用户态驱动与内核模块通过/dev/uioX设备完成最基本的交互,同时使用sysfs来得到相关设备的内存映射、内核驱动等信息,UIO架构见下图

d58808a7425e43b4828ae3e35191955f.png

 相对于UIO,VFIO不仅提供了UIO所能提供的两个基本功能,更多是从安全角度考虑,通过IOMMU(如同常规MMU,需要芯片上支持,如Intel VT-d)支持DMA重映射等技术,把设备I/O、中断、DMA暴露到用户空间从而可以在用户空间完成设备驱动的框架

有了Linux内核模块UIO、VFIO的支持,SPDK还引入异步轮询方式取代中断处理、通过绑定CPU核避免核间缓存同步及资源的无锁化、使用大页内存+hugetlb优化缺页异常引起的性能下降

SPDK 用户态应用框架

为了更好地发挥底层NVMe SSD的性能优势,除了用户态驱动,SPDK还提供了一套编程框架

e800e0ba73a344d9a68b3dd52db75459.png

 总的说来,SPDK的应用框架可以分为:1.对CPU core和线程的管理;2. 线程间的高效通信;3. I/O的处理模型;4.数据路径的无锁化机制

SPDK的原则是使用最少的CPU核和线程来完成最多的任务,使用DPDK的EAL库,通过CPU核绑定函数的亲和性,限制对CPU的使用,每个核上运行一个reactor thread,SPDK提供了一个Poller机制,所谓Poller其实就是一个用户定义函数的封装,通过spdk_poller_register()注册,并在Reactor的while循环中检查Poller的状态,并进行调用。

SPDK放弃了传统的、低效的加锁方式进行线程间通信,是同一个线程只执行自己所管理的资源SPDK提供了事件调用机制,本质是每个Reactor对应的数据结构维护一个Event事件的环,这个环是多生产者但消费者模型,这个环上有锁的机制保证,相比于线程间的锁机制,要高效的多

SPDK用户态块设备层

44b62ae6b5334e7a9a1f9e2631d327ad.png

SPDK最下层为驱动层,管理物理或虚拟设备,也管理本地设备或网络设备

中间层为通用块层,实现对不同后端的支持,提供对上层的统一接口,包括逻辑卷的支持、流量控制等存储服务。这一层也提供了对Blob(Binary Larger Object)及简单用户态文件系统BlobFS的支持

最上层为协议层,包括NVMe、SCSI等协议,可以更好的与上层应用结合

SPDK应用框架采用优化思想,在同用块层也是类似的实现。包括内存资源分配、I/O资源池、Buffer资源池等,即考量全局总的分配数量,也考虑每个CPU核独享的资源

搭建SPDK环境

下载SPDK:https://github.com/spdk/spdk.git,并完成编译、安装

# 下载spdk code & make spdk
root@nvme:~# cd /data/github/
root@nvme:/data/github# git clone https://github.com/spdk/spdk.git
root@nvme:/data/github# cd spdk
root@nvme:/data/github# git submodule update --init

# 安装依赖
root@nvme:/data/github/spdk# ./scripts/pkgdep.sh

# configure with debug
root@nvme:/data/github/spdk# ./configure --enable-debug

# make & make install
root@nvme:/data/github/spdk# make && make install 

欢迎转载,请注明出处

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值