0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

从内核中NVMe IO框架来看其中存在的问题

Linux阅码场 来源:lp 2019-04-15 13:59 次阅读

NVMeSSD具有高性能、低时延等优点,是目前存储行业的研究热点之一,但在光鲜的性能下也同样存在一些没有广为人知的问题,而这些问题其实对于一个生产系统而言至关重要,例如:

QoS无法做到100%保证;

读写混合情况下,与单独读相比,性能下降严重,且读长尾延迟比较严重;

所以如何利用好NVMe盘的性能,并更好的为业务服务,我们需要从硬件Linux内核等多个角度去剖析和解决。

从内核中NVMe IO框架来看其中存在的问题

当前Linux内核中对NVMeSSD的访问是通过MQ框架来实现的,接入NVMe驱动后直接略过IO调度器,具体实现上来说是从blocklayer中的通用块层回调make_request从而打通上下层IO通路。示意图如下,这里面有几个关键的点:

IO发送过程

MQ的框架提升性能最主要的将锁的粒度按照硬件队列进行拆分,并与底层SSD的队列进行绑定,理想的情况每一个CPU都有对应的硬件发送SQ与响应CQ,这样可以并发同时彼此之前无影响。按照NVMeSPEC协议中的标准,硬件最多支持64K个队列,所以理想情况下硬件队列个数将不会是我们需要担心的地方。但是实际情况又如何呢?由于硬件队列的增加会给NVMeSSD带来功耗的增加,所以不同的厂商在设计硬件队列个数时的考量是不同的,比如intelP3600支持32个队列,intel最新的P4500支持16384个,但是SUMSUNGPM963却只支持到8个。那么当CPU的个数超过硬件的队列个数,就会出现多个CPU共用一个硬件队列的情况,对性能就会产生影响。

下面使用SUMSUNGPM963做一个简单的测试:

也就是整个IOPS可以达到50w

如果使用同一个硬件队列

整个IOPS只有44w,性能下降12%,主要原因是多个CPU共用硬件队列进行发送的时候会有自旋锁争抢的影响。所以对于共用硬件队列的情况下,如何绑定CPU是需要根据业务的特点来确定的。

IO响应过程

IO响应过程中最主要问题是中断的balance,由于默认linux中并没有对NVMe的中断进行有效的绑定,所以不同的绑定策略会带来截然不同的性能数据。不过在我们的实际测试中,虽然我们没有做中断的绑定,但是貌似不管是性能还是稳定性的下降并没有那么严重,什么原因呢?根据我们的分析,这里面最主要的原因是(后面也会提到),我们并没有大压力的使用NVMe盘,所以实际的应用场景压力以及队列深度并不大。

从应用本身的IO Pattern来看使用NVMe问题

我们在评测一个NVMeSSD的性能的时候,往往都是通过benchmark工具,例如见1,见2。

然而这些测试的结果与业务实际使用NVMeSSD看到的性能相比差距很大。原因是因为这些性能测试存在两个比较大的误区,因而并不能反映生产系统的真实情况。

1. 片面夸大了NVMe盘的性能

从上面两篇文章中的测试中我们可以看到,大多数压测中使用的队列深度为128,并且是用libaio这样的异步IO模式来下发IO。但是在实际应用场景中很少有这么大的队列深度。在这种场景下,根据“色子效应”,并不会将NVMe盘的并发性能充分发挥出来。

2. 低估了NVMe的长尾延迟

然而在另外一些场景下,队列深度又会非常高(比如到1024甚至更高),在这种情况下NVMeSSD带来的QoS长尾延迟影响比上面的benchmark的测试又严重得多。

所以综合起来看,这种评测选择了一个看上去没啥大用的场景做了测试,所以得出的结果也对我们实际的应用基本没有参考价值。那么问题出在什么地方么?

问题分析

首先让我们再次强调一下一般评测文章中benchmark进行的测试场景的特点:

大多是fio工具,开启libaio引擎增加IO压力

队列深度到128或者256

在这种场景下确实基本都可以将NVMe盘的压力打满。

在展开分析问题的原因之前,我们先看看Linux内核的IO栈。

在实际应用中,VFS提供给应用的接口,从IO的特点来分类,大致上可以分为两类:directIO与bufferIO。使用directIO的业务大多在应用本身就已经做了一层cache,不依赖OS提供的pagecache。其他的情况大多使用的都是bufferIO。linuxkernel中的blocklayer通过REQ_SYNC与~REQ_SYNC这两种不同的标志来区分这两类IO。大家常用的directIO这个类型,内核要保证这次IO操作的数据落盘,并且当响应返回以后,应用程序才能够认为这次IO操作是完成的。所以是使用了这里的REQ_SYNC标志,而对应的bufferIO,则大量使用了~REQ_SYNC的标志。让我们一个一个看过去。

direct IO

由于在实际使用方式中AIO还不够成熟,所以大多使用directIO。但是directIO是一种SYNC模式,并且完全达不到测试用例中128路并发AIO的效果。这主要两个方面原因:

direct io在下发过程中可能会使用文件粒度的锁inode->i_mutex进行互斥。

前面说的IO SYNC模式

也就是说,我们很难通过directIO来达到压满NVMe盘的目的。如果一定要打满NVMe盘,那么一方面要提高进程并发,另外一方面还要提高多进程多文件的并发。而这是生产系统中很难满足的。

buffer IO

我们再来看看bufferIO的特点。下面我使用了比较简单的fio通过bufferIO的模式下发,而且通过rate限速,我们发现平均下来每秒的数据量不到100MB,整个IO的特点如下:

抓取了下submit_bio在每秒的调用次数并分析可以得出,bufferIO在下刷的时候并不会考虑QD的多少,而是类似aio那样,kworker将需要下发的脏页都会bio形式下发,而且不需要等待某些bio返回。注意这里面有一个细节从qusize观察到IO最大值986,并没有达到百K,或者几十K,这个原因是由本身MQ的框架中tag机制nr_request决定,目前单Q设置默认值一般为1024。总之bufferIO这样特点的结果就是突发量的高iops的写入,bufferIO对于应用程序来说是不可见的,因为这是linuxkernel的本身的刷脏页行为。但是它带给应用的影响确实可见的,笔者曾经总结过异步IO的延时对长尾的影响,如下图所示,分别是bufferIO与directIO在相同带宽下延时表现,可以看出这延迟长尾比我们简单的通过fiobenchmark测试严重的多,特别是盘开始做GC的时候,抖动更加严重;而且随着盘的容量用着越来越多,GC的影响越来越大,长尾的影响也是越来越严重。

在HDD的时代上面的问题同样会存在,但是为什么没有那么严重,原因主要是HDD大多使用CFQ调度器,其中一个特性是同步、异步IO队列分离。并且在调度过程中同步优先级比较高,在调度抢占、时间片等都是同步优先。

解决问题

前面描述了使用NVMe硬盘的严重性,下面介绍一下如何解决这些问题。(1)MQ绑定的问题,需要根据当前业务的特点,如果硬件的队列小于当前CPU的个数,尽量让核心业务上跑的进程分散在绑定不同硬件队列的CPU上,防止IO压力大的时候锁资源的竞争。

(2)中断绑定CPU,建议下发的SQ的CPU与响应的CQ的CPU保持一致,这样各自CPU来处理自己的事情,互相业务与中断不干扰。

(3)解决directIO状态下长尾延迟,因为长尾延迟是本身NVMeSSDController带来,所以解决这个问题还是要从控制器入手,使用的方法有WRR(WeightRoundRobin),这个功能在当前主流厂商的最新的NVMeSSD中已经支持。

(4)解决bufferIO状态下长尾延迟,可以通过控制NVMeSSD处理的QD来解决,使用的NVME多队列IO调度器,充分利用了MQ框架,根据同步写、读延迟动态调整异步IO的队列,很好的解决bufferio带来的长尾延迟。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10824

    浏览量

    211127
  • Linux
    +关注

    关注

    87

    文章

    11225

    浏览量

    208906
  • nvme
    +关注

    关注

    0

    文章

    217

    浏览量

    22582

原文标题:你所不知道到的NVMe

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Xilinx FPGA NVMe Host Controller IP,NVMe主机控制器

    ,实现必须以及可选的NVMe Admin Command Set和NVM Command Set,实现对PCIe SSD的复位/断电管理、IO(Page)读写、DMA读写和数据擦除功能,提供用户一个
    发表于 02-21 10:16

    Xilinx FPGA高性能NVMe SSD主机控制器,NVMe Host Controller IP

    ,实现必须以及可选的NVMe Admin Command Set和NVM Command Set,实现对PCIe SSD的复位/断电/SMART/Error Information管理、IO(Page
    发表于 03-27 17:23

    高性能NVMe主机控制器,Xilinx FPGA NVMe Host Accelerator IP

    ,实现必须以及可选的NVMe Admin Command Set和NVM Command Set,实现对PCIe SSD的复位/断电/SMART/Error Information管理、IO(Page
    发表于 04-10 22:55

    ThreadX内核的IAR方式移植和设计框架

    了解后再来看,这样将事半功倍。但是本章的工程模板框架一定要学习。虽然本章节是以我们开发板为例进行移植的,但是教会大家如何移植到自己的板子上以及移植过程的..
    发表于 08-10 06:47

    RK3399 Android7.1系统WiFi的SDIO和电源框架介绍

    1、WiFi的SDIO和电源框架  Platform: RK3399  OS: Android 7.1  Kernel: v4.4.83  框架:  引用网友一张框图,画得很不错  
    发表于 11-30 17:47

    LX2160用RT内核检测不到NVME怎么解决?

    GB (976773168 x 512) 在下一阶段,nvme 磁盘不见了。附加了带/不带 rt 内核的引导日志
    发表于 03-15 08:19

    Nvme硬盘挂载失败如何解决?

    内核启动时卡住,然后提示 nvme nvme0: I/O 401 QID 4 timeout, completion polled,硬盘型号为:致态 PC005 Active 512GB
    发表于 09-12 06:35

    网络IO套路分享

    无情的挂起,等待内核完成操作,因为此时的内核可能将CPU时间切换到了其他需要的进程,在我们的应用程序看来感觉被卡主(阻塞)了。 阻塞IO 传统阻塞
    的头像 发表于 10-13 14:52 1883次阅读
    网络<b class='flag-5'>IO</b>套路分享

    如何使用Linux内核实现USB驱动程序框架

    Linux内核提供了完整的USB驱动程序框架。USB总线采用树形结构,在一条总线上只能有唯一的主机设备。 Linux内核主机和设备两个角度观察USB总线结构。本节介绍 Linux
    发表于 11-06 17:59 20次下载
    如何使用Linux<b class='flag-5'>内核</b>实现USB驱动程序<b class='flag-5'>框架</b>

    NVMe over Fabrics的优势是什么?

    NVMe- oF字面上来看是网络上的NVMe协议的扩展,其扩展范围远远超出了目前搭载SSD的服务器。NVMe早在2011年就出现了,而fa
    的头像 发表于 01-14 09:12 5228次阅读

    Linux内核开发框架学习资料汇总

    Linux内核开发框架学习资料汇总
    发表于 06-17 09:29 24次下载

    OpenHarmony工作委员会PMC委员万承臻带你领略OpenHarmony3.1内核框架

    OpenHarmony工作委员会PMC委员万承臻带你领略OpenHarmony3.1内核框架 OpenHarmony各版本不断迭代不断完善;今天以“共建新技术、开拓新领域”作为
    的头像 发表于 04-25 17:12 2286次阅读
    OpenHarmony工作委员会PMC委员万承臻带你领略OpenHarmony3.1<b class='flag-5'>从</b><b class='flag-5'>内核</b>到<b class='flag-5'>框架</b>

    信号驱动IO与异步IO的区别

    , 是开始处理IO, 这个时候还是存在阻塞的,将数据内核态拷贝进入到用户态的过程至少是阻塞住的 (应用程序将数据
    的头像 发表于 11-08 15:32 996次阅读
    信号驱动<b class='flag-5'>IO</b>与异步<b class='flag-5'>IO</b>的区别

    linux异步io框架iouring应用

    Linux内核5.1支持了新的异步IO框架iouring,由Block IO大神也即Fio作者Jens Axboe开发,意在提供一套公用的网络和磁盘异步
    的头像 发表于 11-08 15:39 646次阅读
    linux异步<b class='flag-5'>io</b><b class='flag-5'>框架</b>iouring应用

    异步IO框架iouring介绍

    前言 Linux内核5.1支持了新的异步IO框架iouring,由Block IO大神也即Fio作者Jens Axboe开发,意在提供一套公用的网络和磁盘异步
    的头像 发表于 11-09 09:30 2195次阅读
    异步<b class='flag-5'>IO</b><b class='flag-5'>框架</b>iouring介绍