SPDK初认识

8 篇文章 1 订阅

1.为什么要引入SPDK?

1、现在的硬盘SSD从性能、功耗以及密度上都相比传统机械硬盘HDD存在巨大的优势。

2、以前的linuxIO栈针对HDD做了诸多优化:page cache等;内核采用中断方式进行DMA(外部设备不通过CPU而直接与系统内存交换数据的接口技术)。而现在ssd的出现,这样的优化会使ssd的硬盘存在空缺,不能充分利用。

3、以前的方式会存在大量的内核上下文切换和中断,造成大量的延迟和开销。现在spdk采用将设备驱动代码放在用户态,避免内核上下文切换。spdk采用轮询模式代替传统的IO模型。

​ 在传统的I/O模型中,应用程序提交读写请求后进入睡眠状态,一旦I/O完成,中断就会将其唤醒。

​ 轮询的工作方式则不同,应用程序提交读写请求后继续执行其他工作,以一定的时间间隔回头检查I/O是否已经完成。

传统的方式:中断开销只占整个I/O时间【io读取慢】的很小的百分比,因此给系统带来了巨大的效率提升。

现在的方式:持续引入更低时延的持久化设备,中断开销成为了整个I/O时间中不可忽视的部分。所以我们必须区优化,使其达到平衡。

[1]Rocksdb加SPDK改善吞吐能力建设

2.什么是SPDK

首先要明确spdk是一个框架,而不是一个分布式系统,spdk的基石(官网用了bedrock 这个词)是用户态(user space)、轮询(polled-mode)、异步(asynchronous)、无锁(lockless)的NVMe驱动,其提供了零拷贝、高并发直接从用户态访问ssd的特性。其最初的目的是为了优化块存储落盘。但随着spdk的持续演进,大家发现spdk可以优化存储软件栈的各个方面。

很多分布式存储系统都在思考如何吸纳spdk框架,或是采用spdk代表的高性能存储技术,来优化整条IO链路。

2]什么是SPDK,以及什么场景需要它

[3]What is SPDK

3. spdk的设计理念

spdk主要通过引入以下技术,实现其高性能方案。

  1. 将存储用到的驱动转移到用户态,从而避免系统调用带来的性能损耗,顺便可以直接使用用户态内存落盘实现零拷贝
  2. 使用polling模式
    1. 轮询硬件队列,而不像之前那样使用中断模式,中断模式带来了不稳定的性能和延时的提升
    2. 任何业务都可以在spdk的线程中将轮询函数注册为poller,注册之后该函数会在spdk中周期性的执行,避免了epoll等事件通知机制造成的overhead。
  1. 避免在IO链路上使用锁。使用无锁队列传递消息/IO
    1. spdk设计的主要目标之一就随着使用硬件(e.g. SSD,NIC,CPU)的增多而获得性能的线性提升,为了达到这目的,spdk的设计者就必须消除使用更多的系统资源带来的overhead,如:更多的线程、进程间通信,访问更多的存储硬件、网卡带来的性能损耗。
    2. 为了降低这种性能开销,spdk引入了无锁队列,使用lock-free编程,从而避免锁带来的性能损耗。
    3. spdk的无锁队列主要依赖的dpdk的实现,其本质是使用cas(compare and swap)实现了多生产者多消费者FIFO队列。有关无锁队列的实现可以看这篇文章

通俗的来讲spdk运行时会占用满指定的CPU core,其本质就是一个大的while死循环,占满一个cpu core。去连续的跑用户指定的poller,轮询队列、网络接口等等。因此,spdk编程最基本的准则,就是避免在spdk核上出现进程上下文切换。其会打破spdk高性能框架,造成性能降低甚至不能工作。

进程上下文切换会因为很多原因导致,大致列举如下,我们在spdk编程时切忌要避免。笔者就曾遇到因为spdk线程中一个不起眼的系统调用mmap进入了内核,导致整个spdk进程不可服务直到宕机。

  • cpu时间片耗尽
  • 进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程运行。
  • 进程主动调用sleep等函数让出cpu使用权。
  • 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行。
  • 硬件中断会导致CPU上的进程被挂起,转而执行内核的中断服务程序。

4.使用spdk加速NVMe存储

spdk希望通过在用户态直接访问NVMe SSD,而不经过kernel nvme 驱动(bypass kernel)。

spdk将NVMe SSD从内核驱动解绑,再绑定到vfio或者uio驱动上。虽然这两个驱动本身不会对nvme设备做任何初始化操作。但它给了SPDK直接访问nvme设备的能力,后续的初始化和命令下发都由spdk负责。所以spdk访问NVMe SSD的调用基本上都是和nvme命令对应的,如admin cmd spdk_nvme_ctrlr_cmd_set_feature、spdk_nvme_ctrlr_cmd_get_log_page,和io cmd spdk_nvme_ctrlr_alloc_io_qpair、spdk_nvme_ns_cmd_read等等。当然,iouring的sq和cq已经和这里nvme的交互方式比较相似了:)

5. spdk bdev

spdk在上述加速访问NVMe存储的基础上,提供了块设备(bdev)的软件栈,这个块设备并不是linux系统中的块设备,spdk中的块设备只是软件抽象出的接口层。

spdk已经提供了各种bdev,满足不同的后端存储方式、测试需求。如NVMe (NVMe bdev既有NVMe物理盘,也包括NVMeof)、内存(malloc bdev)、不落盘直接返回(null bdev)等等。用户也可以自定义自己的bdev,一个很常见的使用spdk的方式是,用户定义自己的bdev,用以访问自己的分布式存储集群。

spdk通过bdev接口层,统一了块设备的调用方法,使用者只要调用不同的rpc将不同的块设备加到spdk进程中,就可以使用各种bdev,而不用修改代码。并且用户增加自己的bdev也很简单,这极大的拓展了spdk的适用场景。

讲到这里,各位同学应该明白了,spdk目前的的应用场景主要是针对块存储,可以说块存储的整个存储的基石,再其之上我们又构建了各种文件存储、对象存储、表格存储、数据库等等,我们可以如各种云原生数据库一样将上层的分布式系统直接构建在分布式块存储、对象存储之上,也可以将其他存储需要管理的元数据、索引下推到块层,直接用spdk优化上层存储,比如目前的块存储使用lba作为索引粒度管控,我们可以将索引变为文件/对象,在其之上构建文件/对象存储系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值