DPDK技术的诞生虽然主要是为了加速网络报文(小包)的处理, 但是相关技术亦可以应用到存储系统中,用以提高存储系统中网络的效 率,继而提升整个系统的性能。
DPDK作为一个高速处理网络报文的框架,提供了以下重要的思想和技术。
-
用户态的网络驱动:使用轮询方式的用户态网络驱动,替换了基于中断模式的内核态网络驱动。
-
基于大页的内存管理:DPDK的大页机制是预先分配一块内存,进行独立的内存管理。
-
基于pthread的CPU调度机制:目前DPDK使用了pthread开发库,在系统中把相应的线程和CPU进行亲和性的绑定,这样,相应的线程尽可 能使用独立的资源进行相关的数据处理工作。
可以把DPDK运用 在高性能计算或者存储系统上。特别是在网络数据交换密集的应用中, 如果数据之间没有紧耦合的情况下,DPDK的特性可以有助于提高整个数据处理系统的性能,比如提高IOPS、减少时延。
基于以太网的存储系统以太网已经成为当今存储系统中不可缺少的一环。这些存储中的网络大致可以分为两个部分,内部网络和外部网络。内部网络主要是整个 存储系统中各个节点之间的通信(如果存储系统由集群构成)。外部网络是对外的接口,提供相应的服务。
目前,DPDK相关技术主要用于以太网协议的网卡优化。为此,我们这里提到的网络存储系统,都建立在由以太网组成的网络上。
存储阵列或者服务器 利用已有的网络,采用不同的交互协议来提供各种存储服务。这些存储服务可以分为以下几类:文件存储(file)、块存储(block)和对象存储(object)。
下面是几种常见的网络协议:
-
iSCSI协议:运行在以太网的SCSI(Small Computer System Interface,小型计算机系统接口)协议,主要提供块设备服务。
-
NAS协议:可以运行在以太网上提供文件服务。
-
Restful协议:运行在HTTP之上的(http协议亦可以工作在以太 网上),提供相关对象存储服务。
-
运行在以太网协议的FC(Fibre Chanel)协议FCOE:用以访问 传统的SAN(storage area network,存储区域网)提供的存储服务。
首先,我们可以利用DPDK来优化网络驱动,通过无锁硬件访问技术加速报文处理,例如Intel网卡的Flow Director技术将指定的TCP流导 入到特定的硬件队列,针对每个Connection(连接)分配不同的TX/RX 队列。
其次,在Socket协议层,我们可以利用DPDK去除共享数据结构的内核锁,降低内核驱动的延时和上下文切换,加速数据处理,从而实现 高效的用户态网络协议栈。当然,即使有了用户态网络栈的支持,从程序开发的角度来讲,我们还必须保持这个用户网络栈和内核态网络栈接 口的兼容性。理想情况下,所有上层应用程序可以不修改已有的代码, 就无缝地迁移到用户态的软件栈,这样对于软件开发的影响可以降低到最小。
另外,我们还可以使用DPDK技术实现用户态下的存储设备驱动, 最大限度地减少内存拷贝和延时,提高数据吞吐量。
毫无疑问,DPDK对于网络报文的处理,尤其对小尺寸的网络包 (包大小低于1500字节)和并发的网络连接有很大的性能提升。
网络存 储系统可以使用DPDK技术来实现用户态的网络驱动,以避免内核和用 户态之间由于数据拷贝所带来的开销。
这样,就正好解决了网络存储中 的“网络部分”的性能瓶颈。
除此以外,DPDK也可以用来实现用户态的 存储驱动来解决用户态数据到具体存储设备的开销。
另外,在设计新的 网络存储服务的时候,我们需要关注DPDK的并行数据处理框架,利用 DPDK的编程框架更好地发挥DPDK由于并行带来的好处。
另外,无论 是提供文件、对象或块服务,网络存储都需要相应的网络栈,即利 用“已经存在的物理网络”加“上层的的网络协议”。
所以,在把DPDK技 术应用到基于以太网的网络存储中之前,我们需要考量已有的DPDK是 否能够提供一个完整的网络协议栈。
SPDK介绍为了加速iSCSI系在IA平台上的性能,Intel专门提供了一套基于IA 平台上的软件加速库和解决存储方案SPDK(Storage Performance Development Kit),它利用了DPDK框架极大提高了网络存储协议端和 后端的存储驱动的性能。
基于DPDK的用户态TCP/IP栈DPDK只提供了对OSI 7层协议的第2层和第3层的支持,为此需要第4层以上协议(主要是需要TCP或者UDP)支持的应用 程序无法直接使用DPDK。为了弥补这一个问题,SPDK中提供了一个 用户态的TCP/IP协议栈(libuns)。为了高效地利用DPDK对于网络报文快速处理这一特性,一个有效的网络协议栈必须解决兼容性和性能问题。
兼容性:用户态的TCP/IP/UDP协议栈,必须为上层的应用提供一个友好的机制,让用户使用已有的接口,但是可以绕过现有内核的现。这样的方法有很多种,SPDK中的libuns提供了以下的解 决方案:监控打开socket操作相关的文件描述符(file descriptor),当调用标准库操作的时候(诸如linux下是glibc),进行截获,一旦发现是监控的文件描述符,就调用用户态的函数。
性能:为了保持与已有的DPDK的管理机制兼容,我们需要对相应的 TCP/IP栈进行优化,LIBUNS就很好地利用了DPDK的优势。
用户态存储驱动为了更好地发挥DPDK的优势,SPDK提供了一些用户态的存储驱动,诸如基于NVME协议的SSD的用户态驱动。NVME(Non-Volatile Memory Express)是一个基于PCI-e接口的协议。通过优化存储驱动,再配合经过DPDK优化的用户态协议栈,存储网络服务器端的CPU资源占用将被进一步降低。
用户态NVME驱动工作机制:
SPDK在IO管理上使用DPDK提供的PMD机制和线程管理机制,一方面通过PMD避免中断,避免因上下文切换造成的系统开销,另一方面,通过DPDK的线程亲和特性,将指定的IO QUEUE绑定特定的DPDK线程,在线程内部可以实现无锁化,完全避免因资源竞争造成的性能损失。另外,SPDK还引入了DPDK内存管理机制,包括 hugepage和rte_malloc以及rte_mempool,使内存管理更加高效稳定。
SPDK所提供的用户态存储驱动提供了内核驱动相同的功能,但和内核驱动相比,存在以下的区别:
-
使用轮询工作方式。
-
提供了线程的亲和性绑定,避免资源竞争。
-
利用DPDK的内存管理机制,以及利用mmio的方法映射PCI设备上 的寄存器和内存空间。当然,用户也可使用其他的内存管理机制,未必 一定要使用DPDK的内在管理机制。
基于DPDK的用户态存储驱动和内核驱动相比,在功能方面不会有缺失,诸如在可靠性方面可以提供一样的功能,甚至可靠性更高,因为 在内核中如果驱动发生故障,有可能导致内核直接崩溃,而用户态的驱动不会存在这样的问题。
内核态和用户态NVME性能比较目前市场上,采用NVME协议的SSD要比采用SATA和SAS协议的SSD,性能更快,主要体现在IOPS的大幅度提高和时延的大幅度降低。 虽然采用内核来驱动基于NVME的SSD,性能也完全可以达到物理上的标称值,但是会消耗更多的CPU。而基于用户态的NVME的SSD驱动则 可以降低CPU的使用,用更少的CPU来驱动NVME的SSD,也能达到同样的性能。这意味着在同样的CPU配置情况下,用户态的NVME驱动性价比更高。
SPDK中iSCSI target实现与性能实现:SPDK中提供了一个iSCSI target实现的用例,以体现使用DPDK在性 能上确实有相应的提升。 iSCSI客户端的工作流程大致如下:
-
利用DPDK用户态的polling model driver,从网卡中获取数据。
-
数据经过用户态的TCP/IP栈,通过标准的socket接口,转给iSCSI target应用程序。
-
iSCSI target应用程序解析iSCSI协议,转化成SCSI协议,把数据请求发给相应的后端驱动。
-
后端驱动接收数据后,对真实的设备驱动进行相应的读写操作。
-
I/O请求完成后,相关返回数据交给iSCSI target应用程序。
-
iSCSI target应用程序把数据封装成iSCSI协议后,调用标准 socket接口写回数据。
-
用户态的TCP/IP栈得到数据后,进行相应的TCP数据分装,调用DPDK的polling model driver。
-
DPDK polling model driver驱动具体的网络设备,把数据写入网卡。
基于SPDK iSCSI target端的应用对比传统的iSCSI target端的应用, 区别在于:
-
传统的iSCSI target应用一般使用:内核态的iSCSI协议栈+TCP/IP协议栈+中断模式的网卡驱动,比如LIO。(当然也有一些iSCSI target使用 用户态的iSCSI栈,比如TGT。)
-
SPDK中的iSCSI target使用的是:用户态的iSCSI协议栈+TCP/IP协 议栈+DPDK用户态的polling model驱动。
这样的好处在于,减少了用户态和内核态之间数据交换的代价。如果后台的驱动是用户态的,就可以减少两次可能的数据拷贝:第一次, 发生在发送或者接收网络数据的时候;第二次,发生在读写存储设备的时候。



