spdk技术原理简介和实践经验

一、导读

与机械硬盘相比,NVMe-ssd在性能、功耗和密度上都有巨大的优势,并且随着固态存储介质的高速发展,其价格也在大幅下降,这些优势使得NVMe-ssd在分布式存储中使用越来越广泛。由于NVMe-ssd的性能比传统磁盘介质高出很多,使得在整个IO处理过程中,软件部分占用的时间比例大大提升,成为制约存储系统性能的主要因素。为了充分发挥后端NVMe-ssd的性能,intel开发出了存储性能开发工具包-SPDK(Storage Performance Development Kit),和RDMA一样,SPDK也采用了kernel bypass的思想,它提供了一整套工具和库,以实现高性能、全用户态、扩展性强的存储应用程序,旨在大幅缩减存储I/O栈的软件开销,将固态存储介质的性能发挥到极致。

本文先对SPDK 技术进行介绍,更好的了解其实现原理,深入理解其带来性能大幅提升的原因,然后给大家分享下中国移动云能力中心块存储团队将SPDK应用到分布式块存储软件BC-EBS上做的一些工作和使用经验。

二、SPDK技术原理简介

1、SPDK的整体架构

SPDK架构整体分为三层:

存储协议层:SPDK支持的存储应用类型。NVMe-oF target实现了NVMe-oF规范,对外提供基于NVMe协议的存储服务端,支持RDMA和TCP网络;iSCSI Target对外提供基于SCSI协议的存储服务端;vhost-scsi或vhost-blk对qemu提供后端存储服务,qemu可以基于SPDK提供的后端存储为虚拟机挂载virtio-scsi或virtio-blk磁盘。

存储服务层:SPDK bdev相当于内核通用块层,为不同后端设备(NVMe、AIO、RBD、VIRTIO 、ISCSI等)驱动提供通用的API接口。SPDK还在通用块层实现了QoS、磁盘阵列、逻辑卷管理等功能。

驱动层:为不同的后端存储设备提供驱动。图中把驱动细分成两层,和块设备强相关的放到了存储服务层,而把和硬件强相关部分放到了驱动层。

2、SPDK的工作机制

为了更好理解SPDK能实现高性能的原因,我们以下图中的场景为例,分析SPDK工作过程,详解工作过程中用到的关键技术。

图2 / SPDK的工作机制

在图中,一台服务器上插了一张NVMe-ssd卡,划分两个namespace(对操作系统而言,每个namespace相当于一块独立的盘),分别分配给两个虚机使用,采用的vhost-blk方式。根据vhost-user协议,qemu不再进行I/O的转发,只进行控制面的管理工作,如feature的协商、virtqueue初始化等,虚机的前端驱动和宿主机存储后端vhost通过共享内存来进行数据交互,具体的交互过程是基于virtio vring 环来实现的。

假如vm1要下发数据时,虚机将数据的内存地址(guest physical address,简称PGA)放在vring环上,vhost的reactor线程通过poller机制不断的轮询vring环,发现有新添数据时,根据qemu记录的PGA到宿主机虚拟地址(vhosthost virtual address,简称VVA)内存映射关系,使用rte_vhost_va_from_guest_pa函数将GPA转换为VVA供vhost处理。

vhost拿到数据后,经过SPDK bdev层的处理(如io拆分合并、对齐等),根据注册的设备驱动,找到具体的NVMe-ssd设备。为了防止多个thead操作同一个设备引起的资源竞争,SPDK提供了I/O channel的概念,每一个thead拥有不同的I/O channel,在NVMe 中,一个I/O channel就对应NVMe的一个队列(queue pair),这样数据最终就交由NVMe的队列来处理。在创建vhost-blk设备时,会选择reactor的一个线程进行绑定,这样,整个I/O处理过程都在同一个线程中完成。

SPDK能实现高性能,主要得益于以下几种技术:

(1)全用户态:把驱动移到用户态,避免了系统调用的开销,且真正实现了内存零拷贝。

在传统的存储I/O栈中,应用程序和磁盘驱动分别处于用户态和内核态,应用程序为了和磁盘进行交互,需要进行多次的系统调用,并且数据需要在用户空间和内核空间之间拷贝,这两个动作都增加了系统开销,当后端是高速设备时,这部分开销就表现的很突出。

而在SPDK中,将驱动程序移到用户态,在执行调用时避免了用户态和内核态来回切换,将节省大量的处理器时间开销,从而有更多的时钟周期来进行真正的存储工作。虚拟机的前端驱动和宿主机存储后端vhost通过共享内存传递数据,避免了大量的内存拷贝。I/O在宿主机上绕过了内核,路径更短。

(2)SPDK独立的线程模型:一个core只拥有一个thread,该thread上可以执行很多poller(轮询函数),满足run-to-completion(一个线程最好执行完所有的任务)的需求。

vhost进程启动时,可以配置多个轮询线程(SPDK称reactor),每个线程绑定一个core。在创建一个vhost-blk设备时,也需要为该设备绑定一个core,绑定的core和前面reactor的core一致。在每个线程上,SPDK提供了poller的机制,来处理具体的事务。SPDK提供的poller分两种:基于定时器的poller和非定时器的poller。在reactor的while(1)循环中,它会不停的check这些poller的状态,进行相应的调用,同时I/O也会得到相应的处理。由于单个core上只有一个reactor thread,所以同一个reactor thread 中不需要一些锁的机制来保护资源。

(3)线程间的通信方式:Event事件机制,一种轻量型的线程交互方式。

在传统存储模型中,多个线程操作同一个资源,往往是通过锁机制来实现的。为了使同一个thread只执行自己所管理的资源,SPDK提供了Event (事件调用) 机制。该机制的本质是每个reactor对应的数据结构 (struct SPDK_reactor) 维护了一个Event事件的ring (环)。这个环是多生产者和单消费者模型,即每个Reactor thread可以接收来自任何其他Reactor thread 的事件消息进行处理。当然,Event ring处理的同时也在执行reactor的SPDK_poller轮询函数。

每个Event事件的数据结构 (struct SPDK_event) 包括了需要执行的函数、相应的参数以及要执行的core。例如,Reactor A 向Reactor B通信,其实就是需要Reactor B代替Reator A执行函数F(X),这样他们只执行自己管理的资源,更加的高效 。

(4)数据路径的无锁化机制:在I/O路径上采用io_channel技术,避免采用锁机制,能降低时延和提升性能。

对于类似NVMe的多队列设备,SPDK提供一个I/O channel的概念 (即thread和device的一个mapping关系),封装在SPDK_vhost_blk_session结构中。不同的thread 操作同一个device应该拥有不同的I/O channel,每个I/O channel在I/O路径上使用自己独立的资源就可以避免资源竞争,从而去除锁的机制。如上图,后端是NVMe-ssd设备时,一个I/O channel对应NVMe的一个queue pair。

三、目前块存储团队在SPDK上的一些工作

1、ceph场景下使用SPDK遇到的性能问题

在虚拟化qemu+SPDK+librbd使用场景下,SPDK采用 vhost-blk或vhost-scsi协议,在虚机中,我们发现性能很差,不能充分发挥出后端ceph集群性能。通过排查发现,该问题的原因是当前SPDK的架构是为了发挥NVMe类设备的性能而设计的,其特点是SPDK下发的I/O会直接到达硬件,I/O的收割也是SPDK直接轮询硬件,而ceph场景下需要有额外的ceph线程介入来下发收割I/O。当前SPDK线程与ceph线程跑在同一个CPU上,造成了资源竞争,导致IO性能下降。解决方法是将这些ceph线程移到在非SPDK使用的CPU上。经过优化后,性能大幅提升,最大提升了16倍,均接近后端集群的性能。

图3 / 优化前后vhost-blk设备性能对比

图4 / 优化前后vhost-blk设备时延对比

图5 / 优化前后vhost-scsi设备性能对比

图6 / 优化前后vhost-blk设备性能对比

2、SPDK和ceph线程最优绑核方案探索

SPDK能有优异的性能,离不开它优异的线程模型,实际使用过程中核的分配相当重要,从上面可以看出,在后端是ceph的场景下,ceph线程运行的核如果没有规划,性能也可能会很差。在虚机场景下,qemu节点核资源更是有限,使得我们不得不考虑,在qemu+SPDK_vhost_iscsi+librbd方案下, 怎样将qemu节点有限的核资源分配给SPDK reactor和ceph线程, 才能达到最优的性能。下面我们就单SPDK线程、ceph卷占用的CPU核数不同时,对性能的影响,及在后端是ceph场景下,单reactor可发挥的最大性能进行了测试和分析。

(1)测试环境:

测试环境共4台服务器,SPDK和qemu共用一台机器,SPDK采用的vhost-scsi方式。

(2)单SPDK线程,ceph卷占用的CPU核数不同时,对性能的影响:

a、1个ceph卷的场景下,ceph卷绑不同数目的核时能发挥出的性能。其中横坐标表示ceph卷的绑核情况,纵坐标表示ceph卷能发挥的iops性能,单位为K。

图7 / 1个image下ceph线程绑核对性能的影响

b、2个ceph卷的场景下,ceph卷绑不同数目的核时能发挥出的性能。其中横坐标表示2个ceph卷的绑核情况,纵坐标表示2个ceph卷能发挥的总共iops性能,单位为K。

图8 / 2个image下ceph线程绑核对性能的影响

c、3个ceph卷的场景下,ceph卷绑不同数目的核时能发挥出的性能。其中横坐标表示3个ceph卷的绑核情况,纵坐标表示3个ceph卷能发挥的总共iops性能,单位为K。

图9 / 3个image下ceph线程绑核对性能的影响

(3)在后端是ceph场景下,单个reactor可发挥的最大性能(ceph集群随机写性能在140K iops左右):

a、每个卷绑定两个core,增加ceph卷的个数,单reactor下可发挥的最大性能。

图10 / 增加卷数,单reactor可发挥的最大性能

b、在上一步的基础上,5个卷时,增加每个卷绑核的数量,对性能的影响。

图11 / 单个reactor,5个卷,增加绑核可发挥的性能

c、增加reactor个数,和单reactor下的性能进行比较。

图12 / 2个reactor,5个卷,增加绑核可发挥的性能

(4)测试结果分析

a、从图7、8、9 可以看出,单reactor下,增加卷的绑核数,性能发挥出的越好。

b、从图10可以看出,单reactor下,每个卷绑两个核,增加卷的个数,性能发挥的越好,但随着卷的个数增加,性能趋于稳定。

c、由a得出的结论,增加卷的绑核数可以增加性能,在未达到集群最大性能的情况下,尝试5个卷时,增加绑核数,但性能并未增加,说明此场景下,单reactor的性能可能到了瓶颈。

d、为了进一步验证c中单个reactor是否到了性能瓶颈,增加reactor个数后,5个卷,相同的绑核数,可以看出性能发挥的更好,更接近集群最大性能。说明在后端为ceph集群,vhost_scsi+librbd的使用场景下,单reactor可发挥的最大性能在100K左右。

四、结尾

SPDK凭借其优秀的架构和性能获得各个存储厂家的青睐,但目前社区还不太成熟,在和各自的产品融合时,用户态的工作模式与传统内核态I/O模型有较大差异,可参考的使用经验不多,往往会遇到各种各样的问题。中国移动块存储团队目前也在积极的将SPDK引入到我们的块存储产品中,进行性能的优化提升,后续会将更多的使用和优化经验分享给大家,与大家一起进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/249736.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次某竞赛中的渗透测试(Windows Server 2003靶机漏洞)

靶机简介 Windows Server 2003是微软公司于2003年3月28日发布的服务器操作系统,它基于Windows XP/Windows NT 5.1进行开发,并在同年4月底上市。以下是关于Windows Server 2003的详细介绍: 系统名称与发布历程: 该产品最初被命名为…

设计模式——2_0 职责链(Chain of Responsibility)

楼下一个男人并得要死,那家隔壁的一家唱着留声机,对面是弄孩子。楼上有两人狂笑;还有打牌声,河中的船上有女人哭她死去的母亲。人类的悲欢并不相通,我只觉得他们吵闹 ——鲁迅 文章目录 定义图纸一个例子:如…

LEETCODE 170. 交易逆序对的总数

class Solution { public:int reversePairs(vector<int>& record) {if(record.size()<1)return 0;//归并 递归int left,right;left0;rightrecord.size()-1;int nummergeSort(left,right,record);return num;}int mergeSort(int left,int right, vector<int>…

C++:异常体系

异常体系 异常1.C语言传统的处理错误的方式2.C异常概念3.异常的使用3.1异常的抛出和捕获3.2 异常的重新抛出3.3异常安全3.4 异常规范 4.C标准库的异常体系5.异常的优缺点 异常 1.C语言传统的处理错误的方式 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以…

Android super.img解包和打包指南(含工具下载lpunpack、lpmake、lpdump)

本文所有命令均需要在linux 上执行 一、解包 1、将Android sparse image格式的super.img转成二进制文件 $ sudo apt install android-sdk-libsparse-utils $ simg2img super.img super.img.bin 2、下载工具lpunpack 和lpmake、lpdump 以及其依赖库 下载地址:https://downl…

python执行linux系统命令的三种方式

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 1. 使用os.system 无法获取命令执行后的返回信息 import osos.system(ls)2. 使用os.popen 能够获取命令执行后的返回信息 impor…

c++学习第十四讲---STL常用容器---vector容器

vector容器&#xff1a; 1.vector基本概念&#xff1a; vector功能与数组类似&#xff0c;与数组不同的是&#xff0c;vector可以动态扩展。 2.vector构造函数&#xff1a; vector<T> v; //默认构造函数&#xff0c;创建数据类型T的容器 ve…

2022 年全国职业院校技能大赛高职组云计算赛项试卷部分解析

2022 年全国职业院校技能大赛高职组云计算赛项试卷部分解析 【赛程名称】高职组-云计算赛项第一场-私有云【任务 1】私有云服务搭建[10 分]【题目 2】Yum 源配置[0.5 分]【题目 3】配置无秘钥 ssh[0.5 分]【题目 4】基础安装[0.5 分]【题目 5】数据库安装与调优[0.5 分]【题目 …

Cloudreve个人网盘系统源码 支持云存储(七牛、阿里云OSS、腾讯云COS、又拍云、OneDrive) 基于Go框架

现在的网盘动不动就限速&#xff0c;涨价&#xff0c;弄得很是心烦。今天分享一款开源免费的网盘项目&#xff0c;基于 Go 语言开发的 Cloudreve。Cloudreve基于Go框架云存储个人网盘系统源码支持多家云存储驱动&#xff08;从机、七牛、阿里云 OSS、腾讯云 COS、又拍云、OneDr…

05:容器镜像技术揭秘|发布容器服务器|私有镜像仓库

容器镜像技术揭秘&#xff5c;发布容器服务器&#xff5c;私有镜像仓库 创建镜像使用commit方法创建自定义镜像。Dockerfile打包镜像创建apache服务镜像制作 php 镜像 微服务架构创建nginx镜像 发布服务通过映射端口发布服务容器共享卷 docker私有仓库 创建镜像 使用commit方法…

vit细粒度图像分类(八)SIM-Trans学习笔记

1.摘要 细粒度视觉分类(FGVC)旨在从相似的从属类别中识别物体&#xff0c;这对人类准确的自动识别需求具有挑战性和实用性。大多数FGVC方法侧重于判别区域挖掘的注意机制研究&#xff0c;而忽略了它们之间的相互依赖关系和组成的整体对象结构&#xff0c;而这些对模型的判别信…

vue3 [Vue warn]: Unhandled error during execution of scheduler flush

文章目录 前言一、报错截图二、排除问题思路相关问题 Vue3 优雅解决方法异步组件异同之处&#xff1a;好处&#xff1a;在使用异步组件时&#xff0c;有几个注意点&#xff1a; vue3 定义与使用异步组件 总结 前言 Bug 记录。开发环境运行正常&#xff0c;构建后时不时触发下面…

基于C/C++的MFC的IDC_MFCEDITBROWSE2控件不显示ico问题记录

打开资源文件 *.rc文件 &#xff0c;在最上方添加 #if !defined(_AFXDLL) #include "afxribbon.rc" // MFC ribbon and control bar resources #endif 如下图所示&#xff1a;

【SpringCloud】使用OpenFeign进行微服务化改造

目录 一、需求与背景二、OpenFeign 远程调用技术原理三、项目代码演示3.1 引入依赖3.2 实现OpenFeign注解修饰接口3.3 指定 OpenFeign 远程调用接口的扫描路径 四、OpenFeign 在日志中打印Request和Response五、OpenFeign 客户端超时配置六、使用 OpenFeign 实现服务降级6.1 实…

C语言数据结构之二叉树

少年恃险若平地 独倚长剑凌清秋 &#x1f3a5;烟雨长虹&#xff0c;孤鹜齐飞的个人主页 &#x1f525;个人专栏 &#x1f3a5;前期回顾-栈和队列 期待小伙伴们的支持与关注&#xff01;&#xff01;&#xff01; 目录 树的定义与判定 树的定义 树的判定 树的相关概念 树的运用…

网络编程套接字(2)

TCP 简单的TCP网络程序服务端创建套接字 服务端绑定服务端监听服务端接收连接测试服务端处理请求客户端创建套接字客户端连接服务器客户端连接服务器单执行流的服务器客户端为什么会显示连接成功&#xff1f; 多进程版的TCP网络程序让孙子进程提供服务 多线程版的TCP网络程序 简…

设计模式——模板方法模式(Template Method Pattern)

概述 模板方法模式&#xff1a;定义一个操作中算法的框架&#xff0c;而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法模式是一种基于继承的代码复用技术&#xff0c;它是一种类行为型模式。模板方法模式是结…

基于node.js和Vue3的医院挂号就诊住院信息管理系统

摘要&#xff1a; 随着信息技术的快速发展&#xff0c;医院挂号就诊住院信息管理系统的构建变得尤为重要。该系统旨在提供一个高效、便捷的医疗服务平台&#xff0c;以改善患者就医体验和提高医院工作效率。本系统基于Node.js后端技术和Vue3前端框架进行开发&#xff0c;利用其…

【Emgu CV教程】6.8、图像平滑之BilateralFilter()双边滤波

文章目录 一、介绍1.原理2.函数介绍 二、举例1.原始素材2.代码3.运行结果 一、介绍 1.原理 BilateralFilter()双边滤波也是非线性滤波&#xff0c;之前介绍的滤波只考虑空间信息&#xff08;滤波核或邻域&#xff09;&#xff0c;容易造成边缘模糊和细节丢失&#xff0c;相比…

在Windows系统中执行DOS命令

目录 一、用菜单的形式进入DOS窗口 二、通过IE浏览器访问DOS窗口 三、复制、粘贴命令行 四、设置窗口风格 1.颜色 2.字体 3.布局 4.选项 五、Windows系统命令行 由于Windows系统彻底脱离了DOS操作系统&#xff0c;所以无法直接进入DOS环境&#xff0c;只能通过第三方软…