SPDK (Storage performance development kit)是由 Intel 发起,用于使用 NVMe SSD 作为后端存储的应用软件加速库。该软件库的核心是实现了用户态、异步、无锁、轮询方式的 NVMe 驱动。
与传统 Linux 内核的 NVMe 驱动相比,它可以大幅度降低 NVMe command 的延迟,同时提高单 CPU 的 IO 处理能力 IOPS,从而形成一套高性价比的解决方案,例如使用 SPDK 的 vhost 解决方案可以应用于公有云中来加速虚拟机中的 NVMe I/O。
增强型 DC2 是滴滴云高性能解决方案中重要的组成部分,我们通过改进 SPDK 中的 vhost 框架来实现高性能 IO,vhost 架构如下:
SPDK vhost 作为虚拟机存储的后端,以进程的形式在宿主机上运行,通过轮询的方式从共享的 Ring Buffer 中得到虚拟机中的 IO 请求,并进行处理,最后将处理完的数据同样通过 Ring Buffer 的方式通知虚拟机。整个过程不需要锁的保护,没有中断引入的开销,效率极高。这里面主要涉及到下面几个部分:
虚拟机中的存储前端驱动:根据具体使用的协议不同而不同,可能为 virtio blk,virtio scsi,或直接使用原生的 NVMe driver,主要负责接收 IO 请求,并将请求保存到 Ring Buffer 中,等待后端的处理。另一方面,前端驱动还需要处理后端的完成通知。
共享的 Ring Buffer:虚拟机中的前端驱动与宿主中的存储后端共享的内存,用来在两者之间传输数据,命令和执行结果。
SPDK vhost 后端:虚拟机存储的后端实现,真正处理 IO 请求的核心逻辑,通过用户态的存储驱动实现高效的 IO 操作。
传统方案下,虚拟机里面 IO 的处理路径如下:
可以看到,虚拟机中的 IO 请求需要经过非常长的调用栈才能最终得到处理,并且虚拟机和宿主机中的调用栈有很多重复的部分,这大大地增加了 IO 处理延时和吞吐量,最终对业务的性能造成很大的影响。通过使用 SPDK+vhost 解决方案,我们可以大大的缩短虚拟机中的 IO 处理路径,从而达到低延时,高 IOPS 的目的。使用 SPDK+vhost 方案之后,IO 处理调用路径如下:
可以看到,在宿主机这端,IO 请求通过 SPDK 用户态驱动就直接交给硬件处理,大大降低了 IO 处理延时和提高了 IOPS。下面对该方案中各个重要模块进行介绍。
虚拟机存储前端驱动
我们可以使用 virtio-blk 作为虚拟机内部的存储驱动,也可以直接使用原生态的 NVMe 驱动。Virtio-blk 可以实现虚拟机与物理机之间快速的数据传输。Virtio 是一套标准的半虚拟化协议,专门为虚拟化场景进行设计和优化,能极大的提高虚拟机内部 IO 的处理性能。Virtio blk 是在 virtio 协议之上实现的块设备半虚拟化接口,能够像其他接口一样,对设备进行格式化,创建文件系统等操作,另外 Virtio blk 在存储协议层进行了极大了优化,从而减少了协议层的开销。如果在虚拟机内部直接使用原生 NVMe 驱动,该驱动能直接与 SPDK vhost 的后端交互,避免了任何协议转换的开销,从而能达到更高的 IO 性能。
SPDK+vhost
SPDK 的全称是 Storage Performance Development Kit,它是 Intel 发起的一组用来编写高性能,高扩展性的用户态存储应用的工具集。官方网址:https://spdk.io/。SPDK重用了很多DPDK中的一些公共组件,比如内存管理,轮询方式的实现等,SPDK的核心是通过无锁,轮询的方式实现高效的用户态驱动集合:
SPDK 将 NVMe 协议的实现放在用户态,存储应用程序直接通过 SPDK 提供的 API 访问设备,不需要 Linux 内核提供的驱动支持。
SPDK 一个重要的设计理念是无锁化,这样避免了多线程由于对锁的争抢而引入的性能开销。
轮询模式,SPDK 使用轮询方式处理数据,这样避免了传统中断方式由于上下文切换而引入的性能开销。
NVMe SSD
在增强型 DC2 中,我们使用了 Intel 的高性能 NVMe SSD,从协议和物理介质上也保证了快速的 IO 处理。NVMe 协议比传统的 SCSI 带宽更高,延时更低,适合高性能的使用场景。
为了使 SPDK 技术真正产品化,在使用 SPDK 本地存储的情况下,我们加入了 vhost 热升级和 QEMU 热升级的支持,同时还支持 vhost 意外退出的自动恢复机制。这样我们可以在虚拟机完全无感知的情况下,在线热修复 SPDK 和 QEMU 的问题,升级过程中,我们会确保对虚拟机内部运行程序的影响控制在一定的范围内。
通过对 SPDK+vhost 整体方案的改造和产品化,我们使用 fio 工具对虚拟机中的 IO 操作进行性能测试,IO 调度器设置为 noop,fio 进行 IOPS 测试的参数为:–bs=4k --rw=randread/randwrite --direct=1 -numjobs=4 -iodepth=128,在随机读方面,增强型 DC2 本地存储的 IOPS 能达到 73w 左右,随机写能达到 47w 左右。fio 进行延时测试的参数为:–ioengine=psync --bs=4k --rw=randread/randwrite --direct=1 -numjobs=1 -iodepth=1,在随机读方面,强型 DC2 本地存储的延时为 96us,随机写为 23us。
本文转载自公众号滴滴技术(ID:didi_tech)。
原文链接:
https://mp.weixin.qq.com/s/e4UAM7UT8Zq4qJK39S5rrA
评论