windows 写小文件太多,磁盘io优化

时间:2024-03-03 10:49:36

优化方法:

增大io缓存

 不应盲目增加以上队列参数值。这样有可能造成磁盘子系统过载或在启动时引起设备配置报错。因此,仅增加hdisk的queue_depths值并不是最好的方法,而应该同时调整可提交最大IO数量。当queue_depths和发送至磁盘子系统的IO数量同时增加时,IO响应时间可能会增加,但同时吞吐量也得到了提升。当IO响应时间接近磁盘超时时间,则说明所提交IO超过了磁盘能够处理的界限。如果看到IO超时并在错误日志中报出IO无法完成,说明可能有硬件问题,或需要缩短队列。

 

调整queue_depths的一条法则是:对于随机读写或队列未满的情况,如果IO响应时间超过15ms,就不能再增加queue_depths值。一旦IO响应时间增加,瓶颈就从磁盘和adapter队列转移至磁盘子系统。调整队列长度应依据:1)实际应用程序产生的IO请求数,2)使用测试工具以观察磁盘子系统的处理能力。其中,1)为主要依据。

 

IO队列有以下四种状态:

  1. 队列已满,IO等在hdisk或adapter驱动层
  2. 队列未满,IO响应时间短
  3. 队列未满,IO响应时间长
  4. 队列未满,IO提交速度快于存储处理速度并导致IO丢失

 

我们需要把队列调整为2或3的状态。情况3表明瓶颈不在hdisk驱动层,而很有可能在磁盘子系统自身,也有可能位于adapter驱动层或SAN。

 

第4种情况是应该避免的。受限于存储IO请求和数据的内存大小,所有磁盘和磁盘子系统都有IO执行数量的限制。当存储丢失IO时,主机端超时,IO将被重新提交,同时等待该IO的事件将被暂停。CPU为了处理IO多做了很多事情,这种情况应该避免。如果IO最终失败,将会导致应用程序崩溃或更严重的结果。所以必须仔细确认存储的处理极限。

合理的平均IO响应时间:

假设队列中没有IO,一次读操作将会占据0至15ms,取决于寻址时间,磁盘转速,以及数据传输时间。之后数据从存储移动至主机。有时数据位于磁盘读缓存,这种情况下IO响应时间约为1ms。对于大型磁盘系统在正常工作状态下,平均IO响应时间约为5-10ms。当随机读取小数据耗时超过15ms时,表明存储较为繁忙。

 写操作通常将数据写入cache中,平均耗时不到2.5ms。但是也有例外:如果存储同步将数据镜像至远端,写操作将耗费更长时间。如果写入数据量较大(多于64KB)则数据传输时间会显著增加。没有cache的情况下,写时间的读时间差不多。

 如果IO是大块顺序读写,除了传输时间较长,IO会暂存于磁盘物理层队列,IO响应时间远高于平均值。例如:应用提交50个IO(50个64KB顺序读),最初几个IO会获得较快的响应时间,而最后一个IO必须等待其他49个完成,从而耗费很长的响应时间。

Windows五种IO模型性能分析

重叠I/O模型的另外几个优点在于,微软针对重叠I/O模型提供了一些特有的扩展函数。当使用重叠I/O模型时,可以选择使用不同的完成通知方式。 

采用事件对象通知的重叠I/O模型是不可伸缩的,因为针对发出WSAWaitForMultipleEvents调用的每个线程,该I/O模型一次最多都只能支持6 4个套接字。假如想让这个模型同时管理不止64个套接字,必须创建额外的工作者线程,以便等待更多的事件对象。因为操作系统同时能够处理的事件对象是有限的,所以基于事件对象的I/O模型不具备伸缩性。 
使用完成例程通知的重叠I/O模型,因为以下几个原因,也不是开发高性能服务器的最佳选择。首先,许多扩展功能不允许使用APC(Asyncroneus Procedure Call,异步过程调用)完成通知。其次,由于APC在系统内部特有的处理机制,应用程序线程可能无限等待而得不到完成通知。当一个线程处于“可警告状态”时,所有挂起的APC按照先进先出的顺序(FIFO)接受处理。现在考虑这样一种情况,服务器已经建立起了一个连接,并且调用含有完成例程指针的WSARecv投递了一个重叠I/O请求。当有数据到达时(即I/O完成时),完成例程执行并且再次调用WSARecv抛出另外一个重叠I/O请求。一个APC抛出的I/O操作需要一定的时间才能完成,所以这期间可能另外一个完成例程等待执行(比如本次WSARecv还没接收完时,又有一个新的客户接入并发来数据),因为还有更多的数据需要读取(上一个客户发来的数据尚未读完)。只要(投递WSARecv的)那个套接字上还有“未决”(未接收完)的数据,就会导致调用线程长久阻塞。 
基于完成端口通知的重叠I/O模型是Windows NT系统提供的一个真正支持高伸缩性的I/O模型。在上一章中,探讨了Winsock几种常见的I/O模型,并且说明了当应对大规模客户连接时,完成端口是最佳的选择,因为它提供了最好的伸缩性。 
对不同Winsock I/O模型的性能测试结果如图1所示。其中服务器采用Pentium 4 1.7 GHz Xeon的CPU,768M内存;客户端有3台PC,配置分别是Pentium 2 233MHz ,128 MB 内存,Pentium 2 350 MHz ,128 MB内存,Itanium 733 MHz ,1 GB内存。服务器、客户端安装的操作系统都是Windows XP。

image

图1 不同I/O模型的性能比较 

1.分析图表1提供的测试结果可知,在所用的I/O模型中,阻塞模式性能最差。这个测试程序中,服务器为每个客户创建两个线程:一个负责处理数据的接收,一个负责处理数据的发送。在多次测试中的共同问题就是,阻塞模式难以应对大规模的客户连接,因为它在创建线程上耗费了太多的系统资源。因此,服务器创建太多的线程后,再调用CreateThread函数时,将返回ERROR_NOT_ENOUGH_MEMORY的错误,这个错误码提示内存不够。那些发出连接请求的客户则收到WSAECONNREFUSED的错误提示,表示连接的尝试被拒绝。 
让我们来看看监听函数listen,其原型如下: 
WINSOCK_API_LINKAGE int WSAAPI listen(SOCKET s, int backlog ); 
参数一s已绑定了地址的监听套接字。 
参数二backlog指定了正在等待连接的最大队列长度。 
参数backdog非常重要, 因为完全可能同时出现几个对服务器的连接请求。例如,假定backlog参数为2时有三个客户机同时发出连接请求,那么前两个会被放在一个“等待处理”队列中,以便应用程序依次为它们提供服务。而第三个连接的请求就会造成一个WSAECONNREFUSED错误。一旦服务器接受了一个连接请求,那个连接请求就会从队列中删去,以便可以继续接收其他客户发出的连接请求。即当一个连接请求到来时队列已满,那么客户将收到一个WSAECONNREFUSED错误。而backlog参数本身的大小就存在着限制,这个限制是由协议提供者决定的。 
故阻塞模式下,由于系统资源的限制,其并发处理量是极难突破的。 


2.非阻塞模式表现出的性能要比阻塞模式稍好,但是占用了太多的CPU处理时间。测试服务器将所有客户对应的socket分类放到FD_SET集合中,然后调用select函数筛选出对应集合中有事件发生的socket,并对集合更新。接下来调用FD_ISSET宏重新判断一个套接字是否在原来加入的FD_SET集合中。随着客户连接数量的增多,这种模型的局限性逐渐凸现。仅仅为了判断一个套接字是否有网络事件发生,就需要对集合FD_SET执行一次遍历!使用迭代搜索来对select更新的FD_SET进行扫描,性能可以得到一些提升。瓶颈在于,服务器必须能够很快地扫描出FD_SET集合中的有网络事件发生的套接字的相关信息。针对这个问题,可以使用更复杂的扫描算法,如哈希搜索,它的效率是极高的。还需要注意的一个问题就是,非分页池(即直接在物理内存中分配的内存)的使用极高。这是因为AFD(Ancillary Function Driver,由afd.sys提供的支持Windows Sockets应用程序的底层驱动程序,其中运行在内核模式下afd.sys驱动程序主要管理Winsock TCP/IP通信)和TCP都将使用I/O缓存,因为服务器读取数据的速度是有限的,相对于CPU的处理速度而言,I/O基本是零字节的吞吐量。 


3.基于Windows消息机制的WSAAsyncSelect模型能够处理一定的客户连接量,但是扩展性也不是很好。因为消息泵很快就会阻塞,降低了消息处理的速度。在几次测试中,服务器只能处理大约1/3的客户端连接。过多的客户端连接请求都将返回错误提示码WSAECONNREFUSED,说明服务器不能及时处理FD_ACCEPT消息导致连接失败,这样监听队列中待处理的连接请求不致于爆满。然而,通过上表中的数据可以发现,对那些已经建立的连接,其平均吞吐量也是极低的(即使对于那些对比特率进行了限制的客户也如此)。 


4.基于事件通知的WSAEventSelect模型表现得出奇的不错。在所有的测试中,大多数时候,服务器基本能够处理所有的客户连接,并且保持着较高的数据吞吐量。这种模型的缺点是,每当有一个新连接时,需要动态管理线程池,因为每个线程只能够等待64个事件对象。当客户连接量超过64个后再有新客户接入时,需要创建新的线程。在最后一次测试中,建立起了超过45,000个的客户连接后,系统响应速度变得非常缓慢。这时由于为处理大规模的客户连接创建了大量的线程,占用了过多的系统资源。791个线程基本达到了极限,服务器不能再接受更多的连接了,原因是WSAENOBUFS:无可用的缓冲区空间,套接字无法创建。另外,客户端程序也达到了极限,不能维持已经建立的连接。 
使用事件通知的重叠I/O模型和WSAEventSelect模型在伸缩性上差不多。这两种模型都依赖于等待事件通知的线程池,处理客户通信时,大量线程上下文的切换是它们共同的制约因素。重叠I/O模型和WSAEventSelect模型的测试结果很相似,都表现得不错,直到线程数量超过极限。 


5.最后是针对基于完成端口通知的重叠I/O模型的性能测试,由上表中数据可以看出,它是所有I/O模型中性能最佳的。内存使用率(包括用户分页池和非分页池)和支持的客户连接量与基于事件通知的重叠I/O模型和WSAEventSelect模型基本相同。真正不同的地方,在于对CPU的占用。完成端口模型只占用了60%的CPU,但是在维持同样规模的连接量时,另外两种模型(基于事件通知的重叠I/O模型和WSAEventSelect模型)占用更多的CPU。完成端口的另外一个明显的优势是,它维持更大的吞吐量。 
对以上各种模型进行分析后,可以会发现客户端与服务器数据通信机制本身存在的缺陷是一个瓶颈。在以上测试中,服务器被设计成只做简单的回应,即只是将客户端发送过来的数据发送回去。客户端(即使有比特率限制)不停的发送数据给服务器,这导致大量数据阻塞在服务器上与这个客户端对应的套接字上(无论是TCP缓冲区还是AFD的单套接字缓冲区,它们都是在非分页池上)。在最后三种性能比较好的模型中,同一时间只能执行一个接受输入操作,这意味着在大多数时间,还是有很多数据处于“未决”状态。可以修改服务器程序使其以异步方式接受数据,这样一旦有数据达到,需要将数据缓存起来。这种方案的缺点是,当一个客户连续发送数据时,异步接受到了大量的数据。这会导致其他的客户无法接入,因为调用线程和工作者线程都不能处理其他的事件或完成通知。通常情况下,调用非阻塞异步接收函数,先返回WSAEWOULDBLOCK,然后数据间断性的传输,而不采取连续接收的方式。 
从以上测试结果,可以看出WSAEventSelect模型和重叠I/O模型是性能表现最佳的。两种基于事件通知的模型中,创建线程池来等待事件完成通知并作后续处理是很繁琐的,但是并不影响以它们来架构中型服务器的良好性能。当线程的数量随着客户端连接数量而逐增时,CPU将花费大量时间在线程的上下文切换上,这将影响服务器的伸缩性,因为连接量达到一定数量后,便饱和了。完成端口模型提供了最佳的可扩展性,因为CPU使用率低,其支持的客户连接量相对其他模型最多。 
I/O模型的选择 
通过上一节对各种模型的测试分析,对于如何挑选最适合自己应用程序的I/O模型已经很明晰了。同开发一个简单的运行多线程的锁定模式应用相比,其他每种I/O模型都需要更为复杂的编程工作。因此,针对客户机和服务器应用开发模型的选择,有以下原则。 
1. 客户端 
若打算开发一个客户机应用,令其同时管理一个或多个套接字,那么建议采用重叠I/O或WSAEventSelect模型,以便在一定程度上提升性能。然而,假如开发的是一个以Windows为基础的应用程序,要进行窗口消息的管理,那么WSAAsyncSelect模型恐怕是一种最好的选择,因为WSAAsyncSelect本身便是从Windows消息模型借鉴来的。采用这种模型,程序需具备消息处理功能。 
2. 服务器端 
若开发的是一个服务器应用,要在一个给定的时间,同时控制多个套接字,建议采用重叠I/O模型,这同样是从性能角度考虑的。但是,如果服务器在任何给定的时间,都会为大量I/O请求提供服务,便应考虑使用I/O完成端口模型,从而获得更佳的性能。

 

windows 服务器性能优化 IO 优化三

增加文件系统缓存

磁盘缓存有两种,这两种的主要目的也是不同的。

第一种是硬盘上自带的缓存,他的作用主要是用于提升磁盘性能。早期大多数为512K-2M,现在的主流硬盘都提升到8M,甚 至有部份达到16M以及32M的。由于它们是硬盘上的一个硬件,其容量是不能更改的。

  第二种是指OS或者下载软件在内存上开辟出来的缓冲区,一般都比较大(相对于碰盘上的缓存),并且可以随时更改。它的作用主要是减少碰盘的IO操作,延长磁盘的寿命。

  磁盘缓存对xp运行起着至关重要的作用,但是默认的I/O页面文件比较保守。所以,对于不同的内存,采用不同的磁盘缓存是比较好的做法。

1.运行 \"regedit\";edit; 2.去[HKEY_LOCA

2.去[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\IoPageLockLimit];

3.根据你的内存修改其十六进制值:

64M: 1000; (2M)

128M: 4000; (8M)

256M: 10000; (16M)

512M或更大: 40000. (64M)。

硬盘的缓存

点击电脑桌面上的“开始”/“运行”,键入““msconfig”启动“系统配置实用程序”,跟着选中“system.ini”标签下的“Vcache”项,就可以根据系统的实际情况来调节硬盘的缓存了。在该选项中一般会有三行内容:ChunkSize=1024、MaxFileCache=10240和MinFileCache=10240;其中第一行是缓冲区读写单元值,第二、三行是硬盘的最大和最小缓冲值,等号后的数值都是可以修改的,只要右键单击选中任一行就可以进行修改了。如果你的内存是128MB的话,上面这三行的取值就比较合理了,当然也可以自定。如果不知道该如何设置合适的缓冲值,请“Windows优化大师”帮忙吧,这个软件中有一个“磁盘缓存优化”项,用鼠标就可以方便地设置好缓存;又或者让“Windows优化大师”自动帮你进行优化设置。当硬盘的缓存值足够大时,硬盘就不用频繁地读写磁盘,一来可以延长硬盘的寿命,二来也可以提高数据的传输速度。(在 Widows98 下很简单,只要在 system.ini 的[VCache] 段下设置 MinFileCache 和 MaxFileCache 的大小就可以了,在 Win2000, XP 下这些字段的设置无效了)。

另外,将硬盘的“文件系统缓存”设置为“网络服务器”,可以加快系统对硬盘的访问速度,因为文件系统缓存里存放了硬盘最近被访问过的文件名和路径,缓存越大所能储存的内容也就越多。如果点击“控制面板”/“系统”/“性能”/“文件系统”/“硬盘”,将“此计算机的主要用途”由“台式机”改为“网络服务器”,可以将原来10K左右的缓存增加至近50K左右。 

   启用磁盘写入缓存在“我的电脑”上单击鼠标右键选择“属性->硬件”,打开设备管理器找到当前正在使用的硬盘,单击鼠标[/url]右键选择属性。在硬盘属性的的“策略”页中,打开“启用磁盘上的写入缓存”(如图1)。

  这个选项将会激活硬盘的写入缓存,从而提高硬盘的读写速度。不过要注意一点,这个功能打开后,如果计算机突然断电可能会导致无法挽回的数据丢失。因此最好在有UPS的情况下再打开这个功能。当然,如果你平常使用计算机时不要进行什么重要的数据处理工作,没有UPS也无所谓,这个功能不会对系统造成太大的损失。

控制系统缓存

 让硬盘使用DMA(直接内存访问)

如果你的“爱姬”不是“太后”级的,那么一般来说,你的硬盘已经支持Ultra DMA 100模式了(当然目前支持Ultra DMA 133的硬盘也已经比比皆是了),其最大瞬间传输率为100MB/S,且占用CPU时间更少,那么我们为什么不使用DMA来进行加速呢?可惜在Windows 98的系统默认设置中,该功能却是被禁用的,需要手工打开它。

实现方法:在“控制面板”中,点击“系统-设备管理-磁盘驱动器-GENERIC IDE DISK TYPE46(不同的机器上该值可能有所不同) –属性-设置”(对硬盘而言),然后选择DMA即可。

让硬盘使用更多的内存做cache(高速缓存)

Cache 可以显著提高系统性能,这是人所公知的,不是连cpu都需要一级cache,二级cache甚至三级cache吗?硬盘上面的cache即已无法再变,但是我们可以让硬盘使用内存做cache,这样他们跑起来是不是要块一些?有两点要注意:

(1)要使下面的修改生效,系统必须使用32位的CDFS。不过请放心,Windows 98已经默认使用了。

(2)这里设置的都是物理内存,只有内存在32MB以上效果才能比较明显,否则可能会弄巧成拙。

下面我们就来看一下其实现方法:对硬盘来说,用记事本打开系统目录下的System.ini文件,找到[Vcache]段,在其下面分别写入MinFileCacheSize=xxxx、MaxFileCacheSize=xxxx、ChunkSize=yyyy,其中的XXXX是Cache的大小,以KB为单位,若有16MB内存可取值2048,若有32MB内存可取值4124,若有64MB内存可取值4096等;YYYY是每一个缓存块的大小,一般设置为1024即可。

让硬盘使用FAT32

在分区时即指定让硬盘使用FAT32或者用一些转换程序将硬盘由FAT16转为FAT32,这样不但可以通过更高效地存储数据以节省磁盘空间(大约10%-15%),而且还可以改善磁盘的性能,在使用较少的系统资源的情况下使程序运行加快50%。

实现方法:在Windows 98中,单击“开始-程序-附件-系统工具-驱动器转换器(FAT32)”,然后按操作说明一步步进行即可。

优化文件系统

通过更改文件系统设置,可以显著改善系统性能。

实现方法:在“控制面板”中,单击“系统-性能-文件系统…”,在“硬盘”标签中,将“计算机的主要用途”改为“网络服务器”,“预读式优化”调到“全部”;在“软盘”标签中,将“每次启动计算机时都搜寻新的软盘驱动器”取消(因为默认情况下,软盘驱动程序在每次启动Windows 98时都要扫描新设备,而通过禁止系统启动时检查软驱,让软盘驱动程序仍然使用先前的设置,则可以使系统启动速度更快);在“CD-ROM”标签中,将“追加的高速缓存”调至最大,“最佳的访问方式”选“四倍速或更高速”;在“可移动式磁盘”标签中,选取“启动所有可移动型磁盘驱动器上的后与高速缓存”。

让文件系统也使用Cache

系统在读写文件时要访问文件分配表,而文件系统Cache则可以把刚访问过的文件的路经和文件名存入内存,以加快下一次的访问速度。

设置方法:在注册表的HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\FSTemlates位置下有三个名为“Desktop”、“Mobile”、“Server”的主键,分别对应上述“文件系统属性”对话框中“台式机”、“便携或接驳式系统”、“网络服务器”三个选项。如果使用的是台式机就可对“Desktop”中的字符串“NameCache”、“PathCache”进行修改;MameCache=“80 00 00 00”(可缓冲128个文件夹)、PathCache=“00 10 00 00”(可缓冲4096个8.3格式的文件名,约使用48KB常规内存)。

参考

https://community.emc.com/docs/DOC-18970

https://community.emc.com/thread/129131

https://community.emc.com/thread/145929