基于SPDK 加速框架的高性能PMEM Bdev
随着数据中心搭载了大量的高速网络以及存储设备,对于主机CPU 资源的挑战也越来越大。为了解决这个问题,一般外部外设都附有(R)DMA(Direct Memory Access)[2]的功能。比如在主机上搭载多个PCIe SSD,对于读写SSD的I/O操作,可以依赖SSD设备的DMA功能来完成。但是在主机上搭载了持久内存相关的设备(本文提到的持久内存,主要是 Intel® Optane™ Persistent Memory),情况有所改变。
当我们把PMEM内存配置成为AD(APP Direct)模式的时候,虽然持久内存可以提供数据持久化的功能,但是PMEM并不像其他PCIe外部存储设备那样具有DMA的功能,可以在对PMEM 设备进行读写的时候,减少CPU的压力。于是在SPDK[1]项目中使用PMEM设备,会在CPU负载比较重的情况下,出现一些问题。在这篇文章中我们会介绍具体的问题,以及目前在SPDK中的相应解决方案。
目前SPDK 中直接使用持久内存的问题
SPDK的核心设计思想是利用较少的CPU资源,去尽可能的发挥出存储硬件(比如PCIe SSD)的性能。总的来讲,其核心竞争力是:单CPU core上的高性能I/O设计(高吞吐/高带宽/低延迟)。因为SPDK提供了用户态的高性能I/O 栈,以及提供了一套高效的application framework。当我们的应用开发遵循SPDK application framework的框架开发程序的要义是:希望尽量使用异步以及非阻塞的模式。但是当我们在SPDK框架中整合持久性内存的时候,这个原则几近被打破。主要是由于以下两个原因:
-
PMEM设备不具有DMA功能。即使把PMEM设备变成AD模式,在对PMEM的空间进行读写的时候,依然全程需要CPU 的参与。
-
PMDK[3]库目前的局限性。PMDK提供了一系列的软件库,诸如libpmem, libpmemobj, libpmemblk。目前从SPDK的编程角度来看,存在两个巨大的问题:
a. 目前所有的PMDK API不支持异步操作。虽然SPDK主分支的版本中有一个基于libpmemblk的PMEM bdev的实现,依然遵循了SPDK bdev的接口实现了异步的API,实际上对PMEM的读写是同步的完成。对于PMEM的读写,完全依赖CPU。
b. PMDK没有offloading engine的支持。正因为PMDK主要是用CPU进行PMEM设备的编程,所以目前PMDK中暂时无法有效整合其他的offloading设备。从而无法在应用高负载情况下,解决CPU高度参与的瓶颈问题。
总的来讲,在整个操作PMEM设备的I/O路径上,CPU成为了一个重要的劳动力,没有喘息的机会。
我们可以想象一下在HCI(Hyper Conve