时光荏苒,才过了半年的时间,ssdfans已经有14位不同领域的作者了。我们这些作者有个微信群,大家写了新文章就会发到群里求审。话说上回阿呆班门弄斧,写了篇Linux多队列的文章发到群里显摆,结果技术偏执狂冬瓜哥问了很多问题,从NUMA架构到Cache的机制,阿呆看的都湿了,流汗流湿的。最后冬瓜哥还留了个家庭作业:能不能推出个系列3,讲讲block-mq和scsi-mq的区别。
没办法,谁叫我开了头呢,阿呆只能求助于Bing搜索了,毕竟百度这种时候不顶用,阿呆又懒得翻墙用Google。看了几篇文章,算是有点眉目了,所以再次鲁班门前弄大斧了。为啥是大斧呢?鲁班发明的不是锯子吗?时代在进步,阿呆应该跟光头强借个电锯。
块设备多队列回顾
话说自从Linux内核引入了块设备多队列之后,负责内核SCSI驱动开发的哥们儿也感觉有活干了,摩拳擦掌,给SCSI驱动添加了对block-mq的支持。首先我们来看Linux的存储栈,如下图,用户的读写用统一的接口BIO,BIO发送到Request Layer,这里面有队列,把BIO一个个塞进去,SCSI Layer再从Request Layer的队列中把BIO一个个取出来执行。
这个架构有几个缺点:
- 每个LUN最多支持250K-500K IOPS,每个HBA最多1M IOPS
- IO结果回来后延迟长,因为中断从1个CPU回来,再让另一个CPU执行回调函数
- 队列锁导致竞争和等待,还有不同核心之间cache的共享
- NUMA上扩展性差
看看性能,随着SSD个数增加,性能没有线性增加。
Blk-mq
Linux 3.13内核推出了块设备层多队列机制:blk-mq,就是在request layer单队列改成多队列。如下图,看看左边多队列和右边单队列的对比,多队列是每个CPU核心一个队列,单队列大家共用一个队列。
Scsi-mq
其实scsi-mq的工作就是把scsi的驱动代码改成支持blk-mq,细节阿呆就不说了,毕竟已经写过多队列了,都差不多,无非程序员再显摆一下自己的技术,选择性的支持,同时多一些个性化的功能。3.17内核增加了scsi-mq支持,有兴趣可以试试。
来看看性能吧,很快就把HBA给跑满了。看起来HBA只能跑512MB/s,太弱了,这还是SAS吗?
再来看看1个SSD,多线程的性能,完爆单队列。
理想很丰满,现实很骨感
看了前面的描述,你是不是想马上使用多队列了?其实多队列并没有传说中那么美好,还是要在自己的系统中实测才能知道真相。美国橡树岭国家实验室的一个研究员在Lustre分布式文件系统中实际测试了scsi-mq的性能。首先来看单个SSD 4KB顺序写,下图中2.6.32是单队列,3.18 mq是blk多队列,硬件单队列,3.18 mq+mc是blk硬件都是多队列。结果,单队列和mq很接近,而mq+mc竟然是最差的!
上图是只有一个SSD,多个线程测试。再试一下单线程,多个SSD的情况,很遗憾,mq+mc继续垫底,单队列依然不差。
算了,咱们不看性能了,看看延迟吧。看看下表最后一列,4KB写延迟2.6.32内核单队列和4.0内核多队列相比,多队列减少了13.6%,不过用了dm-multipath这个补丁之后,又差不多了,都是130us。
引用:
http://events.linuxfoundation.org/sites/events/files/slides/scsi.pdf
Improving Block-level Efficiency withscsi-mq, Blake Caldwell, Oak Ridge National Laboratory