无线电爱好网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

无线电爱好网 首页 技术应用 单片机 查看内容

Multi-queue 架构分析

2022-10-13 10:16| 发布者: 闪电| 查看: 5| 评论: 0

摘要: Linux上传统的块设备层(Block Layer)和IO调度器(如cfq)主要是针对HDD(hard disk drivers)设计的。我们知道,HDD设备的随机IO性能很差,吞吐量大约是几百IOPS(IOs per second),延迟在毫秒级,所以当时IO性能 ...

Linux上传统的块设备层(Block Layer)和IO调度器(如cfq)主要是针对HDD(hard disk drivers)设计的。我们知道,HDD设备的随机IO性能很差,吞吐量大约是几百IOPS(IOs per second),延迟在毫秒级,所以当时IO性能的瓶颈在硬件,而不是内核。但是,随着高速SSD(Solid State Disk)的出现并展现出越来越高的性能,百万级甚至千万级IOPS的数据访问已成为一大趋势,传统的块设备层已无法满足这么高的IOPS需求,逐渐成为系统IO性能的瓶颈。


为了适配现代存设备(高速SSD等)高IOPS、低延迟的IO特征,新的块设备层框架Block multi-queue(blk-mq)应运而生。本文就带大家来了解下Linux 块设备层的blk-mq框架和代码实现。



一、单队列框架和存在的问题



Linux上传统块设备层使用单队列(Single-queue/SQ)架构,如图1所示。简单来说,块设备层负责管理从用户进程到存储设备的IO请求,一方面为上层提供访问不同存储设备的统一接口,隐藏存储设备的复杂性和多样性;另一方面,为存储设备驱动程序提供通用服务,让这些驱动程序以最适合的方式接收来自上层的IO请求。Linux Block Layer主要提供以下几个方面的功能:


  • bio的提交和完成处理,上层通过bio来统一描述发往块设备的IO请求


  • IO请求暂存,如合并、排序等


  • IO调度,如noop、cfq、deadline等


  • IO记账,如统计提交到块设备的IO总量,IO延迟等信息

图1. 单队列的Linux block layer设计

图片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》


由于采用单队列(每个块设备1个请求队列--Requst Queue)的设计,传统的Block Layer对多核体系的可扩展性(scalability)不佳。当系统配备现代高速存储器件时,单队列引入的软件开销变得突出(在多socket体系中尤为严重),成为IO性能的瓶颈。多核体系中blk-sq的软件开销主要来自三个方面:


  • 请求队列锁竞争:blk-sq使用spinlock(q->queue_lock)来同步IO请求队列的访问,每次往请求队列中插入或删除IO请求,必须先获取此锁;IO提交时如果操作请求队列,必须先获取此锁;IO排序和调度操作时,也必须先获取此锁。这一系列操作继续之前,必须先获得请求队列锁,在高IOPS场景(多个线程同时提交IO请求)下,势必引起剧烈的锁竞争,带来不可忽视的软件开销。从图2中可以看到,Linux- 2.6.32 中scsi+blk-sq,高IOPS场景下,约80%的cpu时间耗费在锁获取上。


图2. 高IOPS场景下cpu热点数据

图片引用自《High Performance Storage with blk-mq and scsi-mq》


  • 硬件中断:高的IOPS意味着高的中断数量。在多数情况下,完成一次IO需要两次中断,一次是存储器件触发的硬件中断,另一次是IPI核间中断用于触发其他cpu上的软中断。


  • 远端内存访问:如果提交IO请求的cpu不是接收硬件中断的cpu且这两个cpu没有共享缓存,那么获取请求队列锁的过程中还存在远端内存访问问题。


图3. blk-sq IOPS吞吐量随cpu数量的变化曲线,blk-sq支持的最高吞吐量大概在1MIOPS

图片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》



二、多队列框架和解决的问题



针对blk-sq存在的问题,Jens Axboe (Linux内核Block Layer Maintainer)提出了多队列(multi-queue/MQ)的块设备层架构(blk-mq),如图4所示:



图4. 两层队列的Block Layer设计

图片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》


blk-mq中使用了两层队列,将单个请求队列锁的竞争分散多个队列中,极大的提高了Block Layer并发处理IO的能力。两层队列的设计分工明确:


  • 软件暂存队列(Software Staging Queue):blk-mq中为每个cpu分配一个软件队列,bio的提交/完成处理、IO请求暂存(合并、排序等)、IO请求标记、IO调度、IO记账都在这个队列上进行。由于每个cpu有单独的队列,所以每个cpu上的这些IO操作可以同时进行,而不存在锁竞争问题


  • 硬件派发队列(Hardware Dispatch Queue):blk-mq为存储器件的每个硬件队列(目前多数存储器件只有1个)分配一个硬件派发队列,负责存放软件队列往这个硬件队列派发的IO请求。在存储设备驱动初始化时,blk-mq会通过固定的映射关系将一个或多个软件队列映射(map)到一个硬件派发队列(同时保证映射到每个硬件队列的软件队列数量基本一致),之后这些软件队列上的IO请求会往对应的硬件队列上派发。


MQ架构解决了SQ架构中请求队列锁竞争和远端内存访问问题,极大的提高了Block Layer的IOPS吞吐量。从图5中,我们可以看到Linux 3.17-rc3 中scsi-mq+blk-mq,与图2相同的高IOPS场景下仅3%的cpu时间耗费在锁获取上。


图5. scsi-mq_+blk-mq高IOPS场景下cpu热点数据

图片引用自《High Performance Storage with blk-mq and scsi-mq》


图6. IOPS吞吐量随cpu数量的变化曲线,blk-mq更加接近raw设备的性能

图片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》



1234下一页

路过

雷人

握手

鲜花

鸡蛋

QQ|关于本站|小黑屋|Archiver|手机版|无线电爱好网 ( 粤ICP备15040352号 ) 无线电爱好技术交流5 无线电爱好技术交流1无线电爱好技术交流9开关电源讨论群LED照明应用、电源无线电爱好技术交流4无线电爱好技术交流8无线电爱好技术交流10无线电爱好技术交流11

粤公网安备 44030702001224号

GMT+8, 2022-10-13 10:16 , Processed in 0.109200 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

返回顶部