您的位置:首页 > 其它

【冬瓜哥手绘】关于IO时延你被骗了多久?

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

假设 A 发送 IO 到 B , A 到 B 之间的路径上有多个处理模块,比如,应用同步调用 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 条通路, IO 从 HBA 驱动队列下发到存储的时候,一次可以下发 4 个而不是 1 个,也就是同一个时刻,会有 4 个 IO 同时在路径上流动。假设在整个 10ms 的时间内,从 HBA 到存储控制器缓存会耗费 4ms 的话,那么如果同一个 4ms 内,有 4 个 IO 同时被下发,那么 4ms 内会有 4 个 IO 执行完毕,而不是只有 1 个,这样算来,每个 IO 从 HBA 到存储缓存平均只耗费了 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个被你问倒,咋样,出逼格了吧?

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



本文转载请注明出自 “ 大话存储 ” 公众号。长按识别二维码关注 “ 大话存储 ” 获取业界最高逼格的存储知识。 看了好的请点赞/转发/红包,平时群里发红包装逼,不如把红包猛烈的砸向冬瓜哥吧!冬瓜哥后续会有更多高逼格的东西出炉。大话存储,只出精品。

长按图片发红包:



长按扫码关注“大话存储”



强赠冬瓜哥真容:



(请注意,冬瓜哥不是西瓜哥,这是两个人,很多人给混淆了,冬瓜哥很早就叫冬瓜哥了)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: