关闭

关于IO时延你被骗了多久?

853人阅读 评论(0) 收藏 举报


每秒执行1000IO,平均每个IO的执行耗费了1000ms/1000IOPS=1ms,所以每个IO的平均时延就是1ms,天经地义,这有什么不对呢?

假设A发送IOBAB之间的路径上有多个处理模块,比如,应用同步调用POSIX接口比如read()后进入阻塞态,后续执行路径进入内核态,首先进入VFS模块来查出IO的符号底层承载实体,比如是某个文件,如果是默认的buffer io则进入page cache管理模块搜索cache,未命中或者用了dio模式,则会继续进入FS查询出块地址,继而进入块层,这一层有软raid、多路径、远程复制、lvm等模块,如果对应的目标并没有纳入这些模块,则继续往下进入io scheduler,最后到scsi协议栈,在经历scsi设备驱动、scsi协议栈核心层、host驱动之后,io请求被发送到host控制器,走出主机到外部网络,最后还要经历一系列的外部网络协议、部件,最终到达磁盘,返回数据要经历相反的过程,从而被应用受到,这一去一回所耗费的时间,是很可观的,这段时间就是IO的时延。

从应用到磁盘,这段路径的时延几乎是固定的,不可变的,每个模块处理每个IO所耗费的时间基本固定,模块数量也固定一般不会绕过,所以这段时间可以被称为固定时延,每个IO的时延决不可能低于这个值。我们来假设这个固定时延是比如10ms

但是,如果应用到磁盘之间有多条路可以并发的话,事情就变的有意思了。如图所示,整个IO执行路径可以分为串行阶段和并行阶段。哪里可以并行呢?如果HBA有多条链路连接到switch,存储系统也有多条路连接到switch,图中存在4条通路,IOHBA驱动队列下发到存储的时候,一次可以下发4个而不是1个,也就是同一个时刻,会有4IO同时在路径上流动。假设在整个10ms的时间内,从HBA到存储控制器缓存会耗费4ms的话,那么如果同一个4ms内,有4IO同时被下发,那么4ms内会有4IO执行完毕,而不是只有1个,这样算来,每个IOHBA到存储缓存平均只耗费了1ms而不是原来的4ms。整条路径的IO时延便会从原来的10ms下降6ms+1ms=7ms。是否看出了猫腻?

单个IO从应用到存储的缓存到底耗费了7ms还是10ms?答案是依然耗费了10ms,单个IO的平均时延依然是10ms。应用层所关心的是单个IO从发出到返回耗费的时间。至于7ms,则是障眼法,其利用了空间维度上的并发性,属于空分复用手段,其提升的只能是吞吐量,而不是单个IO的时延的受益。并发越大,吞吐量越大。

优化真时延,只能减少IO路径上的模块数量,或者优化每个模块的处理时间。NVMe就是这么干的,直接把SCSI协议栈割掉,采用轻量级协议栈,降低真时延。此外,提升吞吐量方面,NVMe协议采用了多个发送和完成队列,对应多个核心,多核心同时执行,空分复用,再加上底层Flash设备的并发度非常高,同一时刻每个芯片均可以执行一个或者多个IO,提升并发度,提升吞吐量。此外,新版的Linux内核的块层队列也被替换为多队列,从更顶层就开始并发,进一步提升吞吐量。

如果将并发阶段的假时延称为“可变时延”的话,那么,单个IO的时延应该=固定时延+可变时延×并发度,这才是真时延。而不少厂商在实际公布的结果中并没有×并发度,让人误以为时延很牛,其实压根不是那回事。下次你再碰到厂商的销售售前向你忽悠时延的时候,大可以问一下他,你这个参数是真时延还是假时延?我保准你问10个人9个被你问倒,咋样,出逼格了吧?

跟着冬瓜哥学习存储知识,保持逼格,永不过时,学到的都是你自己的。本文算是个饭前开胃菜,本周下半周瓜哥会发一篇超级大餐,请留好你的胃口。

转载地址 http://mp.weixin.qq.com/s?__biz=MzAwNzU3NzQ0MA==&mid=209278369&idx=1&sn=7749ac30973791946d0d2fae5513e49b#rd

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1110次
    • 积分:17
    • 等级:
    • 排名:千里之外
    • 原创:0篇
    • 转载:2篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档