SPDK,软件定义存储的催化剂

2016年01月 · 福叔

去年第四季度开始,XSKY团队[1]开始研究英特尔向社区开源的SPDK。借XSky支持Ceph使用 SPDK之际,福叔在学习之中发现,就像软件定义网络(SDN)和网络功能虚拟化(NFV)中的性能利器DPDK,SPDK也极有机会给SDS领域带来革命性的影响。如果朋友们不知道DPDK是干什么的,没有关系,我将在以后抽时间给大家分享下DPDK的学习心得,以及我们把它用在存储领域的一些想法,今天先看看SPDK。(这篇文章的图和大部分内容来自英特尔官方网站公开的技术资料[2][3],加上自己的理解,原英文部分内容的著作权归英特尔公司所有……)

技术背景

固态硬盘正在迅速扩展它在数据中心中的份额,相较于传统存储介质,新的闪存介质具有性能,耗电,机架空间等等方面的优势。随着更新的闪存介质投入市场(如3D NAND),这些优势还在不断扩大。

用户在集成新一代的NVMe设备,如英特尔®P3700这样的“性能怪兽”时,会碰到很大的挑战。因为NVMe硬盘的吞吐量和时延表现太好了(2GB/s左右的读写带宽,45万的每秒随机读和17万的每秒随机写,20μm级别的时延)——就IOPS而言,比传统SAS或SATA温氏磁盘快上千倍,也比之前的SATA SSD快5~10倍。一般存储软件的表现,相对于NVMe来说,在整个IO事务中消耗的时间百分比就显得太多了。换言之,存储软件协议栈的性能和效率在存储整体系统中的地位就显得越来越关键了。举个类似的例子,我们从北京乘飞机到美国三藩,按照现在的飞行速度,在天上需要13个小时。这种情况下,你安检的时间,过海关的时间,候机的时间,加起来3个小时,相对于总共的13+3=16个小时也不算长。设想现在飞机的飞行速度提高了100倍,从首都机场T3起飞后,不到10分钟的飞行时间,就可在加州落地,这时3个小时的地面手续就显得很没有效率了。存储系统中软硬件的协作关系,以及网络、数据库等其他计算机领域都有类似的情况或命题。我们可以把NVMe看做一个硬件进步推动软件革新需求的例子,随着后续比它更快的存储介质投入市场,这种推动力将更为急迫。

为帮助存储OEM和软件定义存储开发商充分利用好新的硬件,英特尔开发了SPDK(Storage Performance Development Kit),包含一套驱动程序,以及一整套端到端的存储参考架构。SPDK的目标是能够把硬件平台的计算、网络、存储的最新性能进展充分发挥出来。自芯片而上进行设计优化,SPDK已展示出超高的性能指标。在仅仅几个CPU核参与下,配上一定数量的NVMe硬盘,并没使用任何附加的offload硬件(如FPGA),使用SPDK的存储系统能轻松达到数百万IOPS。英特尔计划将基于Linux的整个SPDK参考架构源代码免费提供,其中,用户空间的NVMe驱动源代码部分已经通过01.org[3]向社区开放,SPDK中的其他部分组件也将在2016年逐步开源。

软件架构概览

SPDK是如何工作的?它超高的性能实际上来自于两项核心技术:第一个是用户态运行,第二个是轮询模式驱动。下面,让我们分析一下各自细节。

首先,将设备驱动代码运行在用户态,是和运行在“内核态”相对而言的。把设备驱动移出内核空间避免了内核上下文切换与中断处理,从而节省了大量的CPU负担,允许更多的指令周期用在实际处理数据存储的工作上。无论存储算法复杂还是简单,也无论进行去重(deduplication),加密(encryption),压缩(compression),还是简单的块读写,更少的指令周期浪费意味着更好的整体性能。

其次,传统的中断式IO处理模式,采用的是被动的派发式工作,有IO需要处理时就请求一个中断,CPU收到中断后才进行资源调度来处理IO。举一个出租车的例子做类比,传统磁盘设备的IO任务就像出租车乘客,CPU资源被调度用来处理IO中断就像出租车。当磁盘速度远慢于CPU时,CPU中断处理资源充沛,中断机制是能对这些IO任务应对自如的。这就好比是非高峰时段,出租车供大于求,路上总是有空车在扫马路,乘客随时都能叫到车。然而,在高峰时段,比如周五傍晚在闹市区叫车(不用滴滴或者专车),常常是看到一辆车溜溜的近前来,而后却发现后座已经有乘客了。需要等待多久,往往是不可预知的。相信你一定见过在路边滞留,招手拦车的人群。同样,当硬盘速度上千倍的提高后,将随之产生大量IO中断,Linux内核的中断驱动式IO处理(Interrupt Driven IO Process)就显得效率不高了。

操作系统的世界里,除了中断式IO处理的方式(即上面提到的被动的派发式工作),还有一种IO处理方式叫做定点轮询(polling)。还是用出租车的例子,试想在机场外出租车排队接客是怎么工作的——有一个或者多个专门的出租车道,排着一队队等候的出租车,当乘客从航站楼中一涌而出时,一辆辆出租车能够用少于十来秒的时间高效的接走一位乘客,后面的车紧接着跟上处理下一位客人。

PMD就是按照类似的机制工作的,SPDK中其他所有的组件也是按照这个理念设计的。专门的计算资源(特定的CPU核)用来主导存储设备的轮询式处理——就像专门的出租车道和车流用来处理乘客任务,数据包和块得到迅速派发,等待时间最小化,从而达到低延时、更一致的延时(抖动变少)、更好的吞吐量的效果。

那么,轮询模式驱动是否在所有的情况下都是最高效的处理IO的方式呢?答案是“也不尽然”。设想一下,如果航站楼里没有什么旅客出来,乘车的人稀稀拉拉的时候,我们可以看到出租车候车区等候派工的车辆长龙,这些等待的车子完全可以到市区去扫活儿,做些更有意义的事情。同样的道理,对于低速的SATA HDD,PMD的处理机制不但给IO性能带来的提升不明显,反而浪费了CPU资源。

这就是为什么我们在学习计算机课程时,老师会讲所谓“中断驱动IO处理”是比其他大部分IO处理机制更好的调度方式。因为在那个年代,CPU的速度远大于磁盘等存储设备,CPU也没有很多核或线程交给操作系统用来做更特殊的事情。无论如何,是终端驱动处理还是轮询驱动处理,取决于系统硬件的搭配方式,不同的条件会匹配不同的优化策略。

SPDK中包含了多个子组件,通过用户态处理机制和轮询驱动模式相互联系。每个子组件都是为了解决整个存储系统中的某一部分瓶颈问题而存在的。当然,用户可以选择只将这些子组件单独拆出来,用到非SPDK的框架中,去优化他们自己的存储处理堆栈。举例来说,SPDK中有个组件叫用户态网络服务(UNS,UserSpace Network Services)库,这是一个Linux内核TCP/IP协议栈的替代品,能够突破通用TCP/IP协议栈的种种性能限制瓶颈。通过使用用户态的,轮询方式的TCP/IP协议栈,SPDK能够在更少的CPU指令周期条件下处理TCP/IP数据包排序和计算,达到极高的IOPS性能。

SPDK中大概有三类子组件:网络前端、处理框架、后端。

SPDK系统架构图

网络前端子组件包括DPDK网卡驱动和上面提到的用户态网络服务(UNS)。DPDK在网卡侧提供了一个高性能的发包收包处理框架,在数据从网卡到操作系统用户态之间提供了一条快速通道。UNS代码则接续这一部分处理,“crack”了TCP/IP数据包的标准处理方式,并形成iSCSI命令。

从这个环节开始,“处理框架”部分拿到了数据包内容,将iSCSI命令转换为SCSI块级命令。然而,在它将这些命令发到“后端”驱动之前,SPDK提供了一套API框架,让厂商能够插入自己定义的处理逻辑(架构图中绿色的方框)。通过这种机制,存储厂商可在这里实现例如缓存、去重、压缩、加密、RAID计算,或擦除码(Erasure Coding)计算等功能,使这些功能包含在SPDK的处理流程中。在SPDK的开源软件包里,会有这些功能的实现样例——虽然不建议用户直接在为生产环境准备的产品代码里照搬。

最后,数据到达了“后端”驱动层,在这里SPDK和物理块设备交互(读和写操作)。如前所述,SPDK提供了用户态的PMD,支持NVMe设备、LinuxAIO设备(传统spinning硬盘)、RAMDISK设备,以及利用到英特尔I/O加速技术的新设备(CBDMA=3D XPoint?)。这一系列后端设备驱动涵盖了不同性能的存储分层,保证SPDK几乎与每种存储应用形成关联。事实上,英特尔在2015年9月首先开源的SPDK部分就主要包含支持NVMe的用户态轮询模式驱动。

当然,SPDK并不适用于所有的存储架构,这里是官方给出的一些Q&A,帮助存储开发人员迅速找到这项技术的定位:

Q:SPDK包是基于Linux的吗?
A:SPDK仅仅在Linux平台上得到测试和支持。

Q:SPDK的IO路径是运行在用户态吗?
A:SPDK能将IO路径从网卡到硬盘排他化的运行在用户态,提高整体性能和效率。

Q:SPDK的系统架构中的线程模型包含无锁化的PMD吗?
A:事实上,PMD连续的在它所占用的物理线程上运行(在没有IO时并不休眠或放弃处理器资源),因此PMD有自己的线程模型,可以认为是无锁的。

Q:SPDK中使用了与DPDK相似的机制处理网络数据包流量吗?
A:SPDK包含了对DPDK的支持框架,因此熟悉DPDK的开发人员能发现SPDK很容易集成。

Q:SPDK的源代码使用什么开源许可,是否禁止代码再分发?
A:SPDK的一部分源代码是BSD许可的,例如NVMe和CBDMA用户态驱动。其他部分以Intel License许可开源(UNS和用户态iSCSI Target)。但这样的安排也许在将来会改变。无论如何,SPDK的所有源代码都将向社区免费提供。

[1] http://www.xsky.com/

[2]https://software.intel.com/en-us/articles/introduction-to-the-storage-performance-development-kit-spdk

[3]http://www.01.org/spdk