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引入到我们的块存储产品中,进行性能的优化提升,后续会将更多的使用和优化经验分享给大家,与大家一起进步。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言指针学习(1)

前言 指针是C语言中一个重要概念,也是C语言的一个重要特色,正确而灵活地运用指针可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人都应当深入的学习和掌握指针,也可以说不掌握指针就没有掌握C语言的精华。 一、什么是指针 想弄清楚什…

2024年第4届IEEE软件工程与人工智能国际会议(SEAI 2024)

2024年第4届IEEE软件工程与人工智能国际会议(SEAI 2024)将于2024年6月21-23日在中国厦门举办。 SEAI旨在为软件工程与人工智能领域搭建高端前沿的交流平台,推动产业发展。本次会议将汇聚海内外的知名专家、学者和产业界优秀人才,共同围绕国际热点话题、核…

cesium-场景出图场景截屏导出图片或pdf

cesium把当前的场景截图,下载图片或pdf 安装 npm install canvas2image --save npm i jspdf -S 如果安装的插件Canvas2Image不好用,可自建js Canvas2Image.js /*** covert canvas to image* and save the image file*/ const Canvas2Image (function…

红队渗透靶机:LEMONSQUEEZY: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录扫描 1、dirsearch 2、gobuster WEB phpmyadmin wordpress wpscan 登录wordpress 登录phpmyadmin 命令执行 反弹shell 提权 get user.txt 信息收集 本地提权 信息收集 1、arp ┌──(root㉿ru)-[~…

PRBS并行输出

PRBS(Pseudo-Random Binary Sequences)是通过LFSR和特征函数 伪随机数发生器产生的伪随机数序列,通常用于高速数字通信测试。 基本电路(单比特输出) prbs N表示用N比特lfsr尝试伪随机数序列,常用的有N7,9…

win10查看Nvidia显卡、cuda版本

通过cmd命令行查看 打开cmd命令行窗口,在命令行输入: nvidia-smi 即可看到相应的显卡信息,以及显卡支持的cuda版本。 如下图所示,可以看到显卡是"GeForce CTX 1650",cuda版本是11.7

Mac brew教程

一、安装brew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"二、查看brew版本 brew -vbrew -v 三、搜索软件 命令格式:brew search 软件名 eg: brew search nginx四、安装软件 命令格…

Springboot + EasyExcel + Vue 实现excel下载功能

一、添加EasyExcel依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency> 二、后端代码示例 controller&#xff1a; GetMapping("/download&quo…

SwiftUI 动画入门之一:路径动画(Path Animations)

概览 在 SwiftUI 的开发中,我们往往需要使用千姿百态的动画把我们的界面元素妆点的更加鲜活灵动。 如上图所示,我们使用路径动画使折线图更加生动了!这是怎么做到的呢? 在本篇博文中,您将学到以下内容: 概览1. 路径与形状(Path and Shape)2. 路径动画的原理3. 让路径…

Springboot 批量增加redis中的数据,并批量设置过期时间

1. 背景 一个功能需要一次性解析大量数据放到 Redis 中缓存&#xff0c;并且每个 key 都需要设置过期时间&#xff0c;但是 Redis 本身命令不支持批量设置过期时间&#xff0c;RedisTemplate 中也没有相关的方法。 2. 实现方式 1. RedisTemplate 使用 redisTemplate.opsForV…

工业物联网接入网关在制造企业的实际应用-天拓四方

随着工业4.0和智能制造的兴起&#xff0c;工业物联网&#xff08;IIoT&#xff09;已成为工厂自动化的关键驱动力。在这个转变中&#xff0c;工业物联网网关扮演着至关重要的角色。它们充当了设备与企业系统之间的桥梁&#xff0c;实现了数据采集、分析和设备控制等功能。 案例…

linux安装mysql客户端--极速成功版

翻了无数个帖子都没有安装好&#xff0c;遇到了各种各样奇奇怪怪的问题。结果看了菜鸟教程的步骤&#xff0c;一路顺利&#xff0c;5分钟装完。 1、安装前&#xff0c;检测系统是否自带安装 MySQL rpm -qa | grep mysql2、安装mysql 下载 wget http://repo.mysql.com/mysql-…

Modbus协议学习第六篇之基于libmodbus库的示例程序(可以联合Modbus模拟仿真软件进行调试)

前置工作 学了这么多Modbus的知识&#xff0c;如果不进行实际的操作&#xff0c;总感觉懂的不透彻。基于此&#xff0c; 本篇博文就带各位读者来了解下如何通过编写程序来模拟与Modbus Slave仿真软件的通讯。当然了&#xff0c;这里有两个前提&#xff0c;如下&#xff1a; 1.请…

【AutoCAD2023】删除验证组件+桌面应用程序+登陆组件方法

Autodesk删除验证组件桌面应用程序登陆组件方法&#xff1a; :: 建议在安装前找到官方安装包释放后的安装文件所在位置 例如&#xff1a;AutoCAD_2023_Simplified_Chinese_Win_64bit_dlm 删除验证组件Autodesk Genuine Service -> x64\AGS (必删) 删除桌面程序Autodesk Desk…

2023安防行业十件大事,一定有你关心的

2023年对我国安防行业来说&#xff0c;可以说是既充满希望又充满不确定性的一年。经历三年的市场低迷&#xff0c;2023年安防市场开始逐渐回暖&#xff0c;行业景气度缓慢上升。 那么&#xff0c;2023年我国安防行业都发生了哪些值得铭记的大事&#xff1f;哪些事件对安防产业…

浏览器内存泄漏排查指南

1、setTimeout执行原理 使用setInterval/setTimeOut遇到的坑 - 掘金 2、Chrome自带的Performance工具 当我们怀疑页面发生了内存泄漏的时候&#xff0c;可以先用Performance录制一段时间内页面的内存变化。 点击开始录制执行可能引起内存泄漏的操作点击停止录制 如果录制结束…

实现vue3响应式系统核心-shallowReactive

简介 今天来实现一下 shallowReactive 这个 API。 reactive函数是一个深响应&#xff0c;当你取出的值为对象类型&#xff0c;需要再次调用 reactive进行响应式处理。很明显我们目前的代码是一个浅响应&#xff0c;即 只代理了对象的第一层&#xff0c;也就是 shallowReactiv…

wespeaker项目grpc-java客户端开发

非常重要的原始参考资料&#xff1a; 链接: triton-inference-server/client github/grpc java ps&#xff1a; 使用grpc协议的其它项目python/go可以参考git hub目录client/tree/main/src/grpc_generated下的其它项目 其它链接&#xff1a; 想要系统了解triton-inference-ser…

#《AI中文版》V3 第 3 章 知情搜索

参考链接&#xff1a; [1] 开源内容&#xff1a;https://github.com/siyuxin/AI-3rd-edition-notes [2] Kimi Chat官网链接 正文笔记 P90 针对 大型问题。 知情搜索&#xff08;informed search&#xff0c;也称有信息搜索&#xff09;&#xff1a;利用启发式方法&#xff0c…

新版多功能去水印工具微信小程序源码下载+带流量主功能

新版多功能去水印工具微信小程序源码下载&#xff0c;带流量主功能。自带去水印接口的多功能小程序&#xff0c;支持各大平台短视频去水印。 支持保存封面、图集、标题等等&#xff1b;支持本地图片去水印&#xff1b;支持图片拼接&#xff1b;支持九宫格切图&#xff1b;支持…