SPDK简介

SPDK(Storage Performance Development Kit)是Intel发布的存储性能开发工具集

用户使用现在的固态设备,比如Intel® SSD DC P3700 Series Non-Volatile Memory Express(NVMe)驱动,面临一个主要的挑战:因为吞吐量和延迟性能比传统的磁盘好太多,现在总的处理时间中,存储软件占用了更大的比例。换句话说,存储软件栈的性能和效率在整个存储系统中越来越重要。随着存储设备继续发展,它将面临远远超过正在使用的软件体系结构的风险(即存储设备受制于相关软件的不足而不能发挥全部性能)

原理

  • 用户态运行
    避免内核上下文切换和中断将会节省大量的处理开销,允许更多的时钟周期被用来做实际的数据存储。无论存储算法(去冗,加密,压缩,空白块存储)多么复杂,浪费更少的时钟周期总是意味着更好的性能和延迟。这并不是说内核增加了不必要的开销;相反,内核增加了那些可能不适用于专用存储堆栈的通用计算用例的相关开销。SPDK的指导原则是通过消除每一处额外的软件开销来提供最少的延迟和最高的效率。
  • 轮询模式取代中断模式(Polled Mode Drivers, PMDs)
    在传统的I/O模型中,应用程序提交读写请求后睡眠,一旦I/O完成,中断就会将其唤醒。PMDs的工作方式不同,应用程序提交读写请求后继续执行其他工作,以一定的时间间隔回头检查I/O是否已经完成。这种方式避免了中断带来的延迟和开销,并使得应用程序提高了I/O的效率。
    在机械盘时代,中断开销只占整个I/O时间的一个很小的百分比,因此给系统带来了巨大的效率提升。然而,在固态设备的时代,持续引入更低延迟的持久化设备,中断开销成为了整个I/O时间中不能被忽视的部分。这个问题在更低延迟的设备上只会越来越严重。系统已经能够每秒处理数百万个I/O,所以消除数百万个事务的这种开销,能够快速地复制到多个内核中。数据包和数据块被立即分发,等待时间减小到最少,使得延迟更低,一致性延迟更多(抖动更少),吞吐量也得到提高。
  • 无锁机制
    在IO路径上避免采用任何锁机制进行同步,降低时延并提升吞吐量

架构

introduction-to-the-storage-performance-development-kit-spdk-fig2

Hardware Drivers

NVMe Driver

SPDK的基础组件,这个高优化无锁的驱动提供了高扩展性,高效性和高性能。

Inter QuickData Technology

Intel I/O Acceleration Technology(Inter IOAT,英特尔I/O加速技术),这是一种基于Xeon处理器平台上的copy offload引擎。通过提供用户空间访问,减少了DMA数据移动的阈值,允许对小尺寸I/O或NTB的更好利用。

Back-end Block Devices

NVMe-oF Initiator

本地SPDK NVMe驱动和NVMe-oF启动器共享一套共同的API命令。这意味着,比如本地/远程复制非常容易实现。

Ceph RADOS Block Device

Ceph RBD 成为SPDK的后端设备

Blobstore Block Device

由SPDK Blobstore分配的块设备,是虚拟机或数据库可以与之交互的虚拟设备。这些设备得到SPDK基础架构的优势,意味着零拷贝和令人难以置信的可扩展性。

Linux AIO

允许SPDK与内核设备(比如机械硬盘)交互。

Storage Services

Block Device Abstration Layer

这种通用的块设备抽象是连接到各种不同设备驱动和块设备的存储协议的粘合剂。还在块层中提供灵活的API用于额外的用户功能(磁盘阵列,压缩,去冗等等)。

Blobstore

为SPDK实现一个高精简的文件式语义(非POSIX)。这可以为数据库,容器,虚拟机或其他不依赖于大部分POSIX文件系统功能集(比如用户访问控制)的工作负载提供高性能基础。

Storage Protocols

iSCSI Target

建立了通过以太网的块流量规范,大约是内核LIO效率的两倍。现在的版本默认使用内核TCP/IP协议栈。

vhost-scsi target

KVM/QEMU的功能利用了SPDK NVMe驱动,使得访客虚拟机访问存储设备时延迟更低,使得I/O密集型工作负载的整体CPU负载减低。

NVMe-oF Target

实现了NVMe-oF规范。虽然这取决于RDMA硬件,NVMe-oF的目标可以为每个CPU核提供高达40Gbps的流量。

应用方案

spdk_component

网络前端

网络前端子组件包括DPDK网卡驱动和用户态网络服务UNS(这是一个Linux内核TCP/IP协议栈的替代品,能够突破通用TCP/IP协议栈的种种性能限制瓶颈)。DPDK在网卡侧提供了一个高性能的发包收包处理框架,在数据从网卡到操作系统用户态之间提供了一条快速通道。

处理框架

拿到了数据包内容,将iSCSI命令转换为SCSI块级命令。然而,在它将这些命令发到“后端”驱动之前,SPDK提供了一套API框架,让厂商能够插入自己定义的处理逻辑(架构图中绿色的方框)。通过这种机制,存储厂商可在这里实现例如缓存、去重、压缩、加密、RAID计算,或擦除码(Erasure Coding)计算等功能,使这些功能包含在SPDK的处理流程中。

后端

SPDK和物理块设备交互(读和写操作)。如前所述,SPDK提供了用户态的PMD,支持NVMe设备、Linux AIO设备(传统机械硬盘)、RAMDISK设备,以及利用到英特尔I/O加速技术的新设备(CBDMA)。这一系列后端设备驱动涵盖了不同性能的存储分层,保证SPDK几乎与每种存储应用形成关联。

使用及编译

编译安装

SPDK使用了DPDK中的一些功能,编译SPDK需要依赖DPDK,所以需要先编译安装DPDK

编译DPDK

1
2
3
# make config T=x86_64-native-linuxapp-gcc
# make
# make install

默认DPDK会安装到/usr/local目录下

编译SPDK

1
2
# ./configure --with-dpdk=/usr/local
# make

使用

nvme设备插入主机会被系统自动识别。若想使用spdk访问该设备必须现将nvme unbind。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 7.3T 0 disk
└─sda1 8:1 0 7.3T 0 part /
sdb 8:16 0 7.3T 0 disk
sdc 8:32 0 7.3T 0 disk
sdd 8:48 0 3.8G 0 disk
└─sdd1 8:49 0 3.8G 0 part /boot
nvme0n1 259:0 0 1.5T 0 disk

# cd <spdk_dir>/scripts
# sh setup.sh

# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 7.3T 0 disk
└─sda1 8:1 0 7.3T 0 part /
sdb 8:16 0 7.3T 0 disk
sdc 8:32 0 7.3T 0 disk
sdd 8:48 0 3.8G 0 disk
└─sdd1 8:49 0 3.8G 0 part /boot

参考&鸣谢