1.4.2 存取路径
设计和理解存储系统涉及到许多具体的细节,一个最为重要的方法就是分析数据的存取路径。事实上存取路径包括物理过程和逻辑过程,前者是数据在硬件部件上实际流动的过程,而后者是软件对于数据的处理过程。存取路径是指请求和数据在存储系统中传递的通道。而存取路径就是从数据请求到物理存储设备之间的交互通道。之所以称之为交互通道,其原因在于它不是单向的,而是双向的,无论是读还是写过程都需要数据和命令的传输,这两个方面的过程往往占据双向过程中的某一边。
正如在前面讨论计算机系统存储层次结构,物理存取路径的起点或终点是内存,典型物理路径包括系统主机总线、主机I/O总线、主机I/O控制器或者主机总线控制器(HBA),I/O总线或者网络连接、存储设备和外部存储系统,最后是实际的存储介质。需要指出由于存储设备和外部存储系统自身也是一台计算设备,因此它们具有和上述主机内部的物理路径类似的内部物理路径。而数据或者命令在物理路径上流动都需要部件的处理单元参与,并且主机对于存储设备或者系统发出I/O指令(不仅限于处理器的指令集,包括应用程序的I/O请求)触发实际的数据存取过程。
图 1.8显示了同一个主机中两种不同应用分别针对网络存储设备和本地存储设备访问的物理存取路径。事实上,对于网络存储设备的访问物理存取过程还必须包含网络和远程存储设备的内部物理路径,考虑到不同的网络存储设备有不同的内部存取路径,因此只是简单表明网络存储设备。
实际运行时,并不是每次数据存取过程都需要上述全部物理部件的参与。在DAS结构中,数据不需要经过网络传输。考虑在上述物理部件中基本上都存在buffer或者cache,如果需要读的数据已经存在于内存之中,相应的物理存取过程也许仅仅涉及内存操作。
当前对于技术的发展,交换型的数据通道也可能取代传统总线型的物理数据通道成为物理路径的一部分,例如Infiniband高速网络在高性能存储系统中就可以起到系统主机总线的作用,而光纤通道FC也在SAN系统中占据了传统I/O总线的位置。
逻辑存取路径主要涉及存储过程中的软件。逻辑存取路径的软件部分可以包括应用软件、操作系统、文件系统和数据库、卷管理器和设备驱动程序,以及存储设备的嵌入式系统软件等。下面用一个例子来说明逻辑存取路径,如果某个程序需要读取本地磁盘中的一个文件并且该文件还没有被系统缓存,程序通过操作系统提供的系统调用发出读文件请求,而文件系统响应应用程序的请求,通过请求中的文件路径获取该文件所在的卷号和分配表,并对分配表记录逻辑地址发出页请求,由于文件不在内存缓冲区,页请求被发送给卷对应的设备驱动程序,设备驱动程序把页请求转化为对于磁盘驱动器的I/O请求,而磁盘响应驱动程序的请求,把逻辑地址转换为实际的物理地址并读取数据,之后数据再通过请求路径传递给应用程序。而写文件过程的路径和上面一样,只是首先把数据传递给磁盘,而确认信息通过相同的路径返回应用程序。一般把从应用程序到存储设备的过程定义为下行过程,而把存储设备到应用程序的过程定义为上行过程。因此很多研究把应用程序到存储设备软件层次称为I/O功能"栈"。
I/O栈的每一层往往提供请求/响应接口,实际的过程分为同步I/O和异步I/O。同步I/O就是服务程序(线程)只有等待当前请求实际完成后才可以执行下一个请求,而异步I/O是服务程序(线程)在等待当前请求完成构成中,可以响应下一个请求。例如设备驱动程序为维护一个请求队列,文件系统发出I/O请求会进入请求队列,当任务完成后,驱动程序通过回调方式返回数据给文件系统。同样磁盘驱动器也有相同的过程。
大部分数据请求开始于某一个应用程序,这个应用可以是数据库操作、Email服务、Web服务或者系统管理应用。这些应用由用户发起完成特定的功能或者服务,它们通常通过标准的存取接口访问存储设备或者系统。事实上,还有许多I/O请求是由操作系统本身发起的,例如虚拟存储器中的页交换过程。
实际上,物理存取路径和逻辑存取路径是一致的,是实际存取路径在物理和逻辑上的不同表现形式。如果物理存储路径需要通过TCP/IP网络到远程NAS设备存取数据,逻辑存取路径包括本机的TCP/IP协议栈和远程NAS的TCP/IP协议栈。正是由于软件和硬件相互合作才能完成数据请求。
下面以iSCSI为例,分析实际的数据存取路径。Linux的SCSI驱动程序的实现分为三个模块:SCSI上层,SCSI中层,SCSI底层。可以用iSCSI模块替换三层模块中的任意一层来对SCSI命令进行封装并通过TCP/IP网络传输。可以通过替换Linux的SCSI驱动的中层模块来对iSCSI协议进行解释和封装。如图 1.10所示,(1)当用户向一个iSCSI target设备发出访问请求时,应用程序通过系统调用访问文件系统,(2)文件系统首先解释这个I/O命令,分析I/O命令所在的设备和地址。然后它把这个请求发送给SCSI上层驱动程序,(3)SCSI上层驱动程序把相应的I/O命令转化为SCSI命令,并发给iSCSI Initiator,(4)iSCSI Initiator把SCSI命令封装打包,通过网络发送到iSCSI Target模块,(5)当iSCSI Target模块收到iSCSI命令包后,它把iSCSI命令包中的SCSI命令发送到SCSI的底层驱动程序,(6)由SCSI底层驱动程序完成I/O请求。把数据按原路返回给用户。
总之,如果说存储接口为存储系统划分了几个横向具有标准接口的断面,那么一条存取路径就是纵向贯穿存储层次连接从请求发起的应用到数据源的通道。在读数据过程中,读请求顺着特定路径达到物理存储设备,数据准备好后,数据沿着特定道路返还给用户;在写数据过程中,数据沿着特定的路径到达物理存储设备,数据写到物理存储设备后,确认信息返回给用户。
I/O请求的响应时间就是数据和请求命令(或者写确认)在存取路径往返的总延迟。因此一种减少响应时间的方法就是缩短实际的存取路径,而在存储系统每层的接口处设计cache机制提供请求在本层的命中率,从而减少I/O请求的响应时间。
考虑使用并行机制提高存取性能,在大容量存储系统中应用发出的文件读请求需要从多个存储结点获取数据,那么一条存取路径往往在主机系统I/O栈的底层分裂为几个相对独立(横向和纵向)的子I/O路径(I/O路径是位于两个部件或者设备之间传送数据的通道),分别从相应的存储结点读取数据。例如应用通过分布式文件系统存取文件,一个文件请求有可能分裂成对应多个存储结点的相应分条文件发出的子I/O请求。
因此通过分析所有请求的I/O路径及其在每个环节的延迟,能够更好的分析存储系统中各个部件和整体的性能问题,进而为优化系统设计提供支持。