对于闪存存储而言,一切都发生了变化,SSD的性能无论是带宽还是IOPS都非常高,因此,存储的性能瓶颈点从Disk端转移到了CPU、OS以及网络端。
在闪存存储领域,我们可以看到无论在市场、客户还是在研发,大家都在支持NVMe标准,其很重要的一个原因是传统的SCSI已经不能满足性能需求,其变成了存储系统的一个重要性能瓶颈点。从软件层、传输协议效率、软件接口标准、芯片接口、传输链路,传统的SAS/SATA都存在很多不足的地方。今天存储老吴和大家一起分享一下SAS/SATA接口在软件层面的重要性能瓶颈点,从研发的角度来解释为什么SCSI软件层是一个重要的性能瓶颈点。
大家都比较清楚SCSI软件层的组织结构,其主要由三大部分组成:
1, SCSI上层驱动层。这层驱动主要完成SCSI设备的功能,例如磁盘的驱动、Tape的驱动,CD-ROM的驱动都在这层实现。对于磁盘驱动,通常也被称之为SD驱动,实现了一个块设备功能。对上接入块设备驱动层;对下和SCSI中间层对接。
2, SCSI中间层。中间层软件主要完成SCSI命令的处理、出错处理、超时处理等。中间层的上面是各个SCSI的功能驱动;下面是SCSI的底层驱动。
3, SCSI底层驱动。底层驱动实现了SCSI的数据传输和HBA的驱动。在底层可以实现ISCSI的发送器;可以模拟一个SCSI的HBA;当然也可以实现LSI的HBA驱动程序,并通过DMA的方式将数据提交给实际的硬件板卡。
在传统磁盘存储中,性能瓶颈点在磁盘端。CPU处理器、NUMA体系架构、软件的并发性对存储的性能影响几乎为零。存储老吴在07年研发Thin Provisioning逻辑卷系统的时候,试图通过优化锁资源竞争来提升IO性能,结果是预料之中的徒劳。对于磁盘存储来说,CPU性能一直是搓搓有余的。一个磁盘的IOPS最多只能跑到200,所以中断对CPU来说也毫无压力,在这种情况下,SCSI软件层无论如何实现对性能基本是没有影响的。所以,磁盘存储是一个实实在在的IO Intensive应用。
但是,对于闪存存储而言,一切都发生了变化,SSD的性能无论是带宽还是IOPS都非常高,因此,存储的性能瓶颈点从Disk端转移到了CPU、OS以及网络端。在这种情况下,我们再来看一看SCSI的软件栈。如下图所示,每个SCSI设备只提供了一个请求队列(request queue),那么无论系统中存在多少个处理线程,无论系统中存在多少个CPU核,所有的请求都会以竞争的方式入队列。SCSI设备的请求队列是系统的一个竞争资源。
对于SMP系统而言,竞争资源的处理都需要通过加锁的方式来实现访问。在Linux的实现中通过Spinlock的方式对请求队列进行互斥保护。由于SSD性能非常高,所以系统中的CPU都在忙于请求的处理,这些忙碌的CPU最终都需要去竞争请求队列锁,将请求放入队列。这种大量的竞争导致每个CPU的处理效率大为降低,大量时间处于自旋状态,等待获取请求队列锁。从而使得整体IO处理的效率降低,存储性能由于软件上的限制而得不到提升。
针对这个问题,我们做过实际的测试,发现当IO压力上来之后,系统中的CPU绝大部分时间都处于自旋状态,都在竞争请求队列的自旋锁。所以,SCSI层的单请求队列是一个严重的性能瓶颈点。
为了解决这个问题,Linux对SCSI的单队列做了改进,引入了Multi-queue的方式。通过多队列的方式可以减少、避免线程/CPU之间的竞争,可以充分发挥单个CPU处理IO的效率,从而整体提升IO处理的性能。SCSI引入多队列之后的示意图如下图所示:
需要注意的是,在软件上为每个SCSI设备引入多队列之后,同样需要在HBA端为软件访问提供多队列支持,否则性能将会局限在HBA卡上。闪存存储软件的设计与实现和传统存储相比,不仅数据分布、数据的组织形式发生了变化;而且软件的实现效率、CPU并发潜能的挖掘、计算机体系结构的考虑都会变得尤其重要。所以,我一直认为,闪存存储不仅玩的是存储技术,而是高性能计算技术。