如何提高大量较小文件的读写速度或性能

本文关键字:读写 速度 性能 文件 小文 何提高 | 更新日期: 2023-09-27 18:19:25

昨天,我在这里问的问题:如何禁用磁盘缓存在c#调用win32 CreateFile api与FILE_FLAG_NO_BUFFERING。

在我的性能测试显示(写和读测试,1000个文件和总大小220M), FILE_FLAG_NO_BUFFERING不能帮助我提高性能和低于。net默认磁盘缓存,因为我尝试将FILE_FLAG_NO_BUFFERING更改为FILE_FLAG_SEQUENTIAL_SCAN可以达到。net默认磁盘缓存和快一点。

之前,我尝试用mongodb的gridfs功能代替Windows的文件系统,并不好(而且我不需要使用分布式功能,只是品尝)。

在我的产品中,服务器可以通过tcp/ip每秒读取许多较小的文件(60-100k),然后需要将其保存到磁盘上,第三个服务读取这些文件一次(只读取一次并处理)。如果我使用异步i/O是否可以帮助我,是否可以获得最佳的速度和最佳的低cpu周期?有人能给我一些建议吗?或者我仍然可以使用FileStream类?

更新1

内存映射文件是否能达到我的需求。所有文件都写入一个或多个大文件并从中读取?

如何提高大量较小文件的读写速度或性能

如果你的电脑需要5-10秒才能将一个100kB的文件写入磁盘,那么你的电脑要么是世界上最老、最慢的电脑,要么是你的代码效率非常低。

关闭磁盘缓存可能会使事情变得更糟而不是更好。有了磁盘缓存,写操作就会很快,而Windows稍后会执行将数据刷新到磁盘的较慢部分。实际上,增加I/O缓冲通常会显著改善I/O。

你肯定想使用异步写-这意味着你的服务器开始写数据,然后返回响应客户端,而操作系统在后台处理将数据写入磁盘。

写操作不需要排队(因为如果启用了磁盘缓存,操作系统已经这样做了),但是如果所有其他方法都失败了,你可以尝试一下——一次只写一个文件,可以最大限度地减少磁盘查找的需要。

通常对于I/O,使用更大的缓冲区有助于提高吞吐量。例如,不是在循环中将每个字节写入文件,而是在一个write操作中写入一个缓冲区的数据(理想情况下是整个文件,对于您提到的大小)。这将最小化开销(不是为每个字节调用write函数,而是为整个文件调用一次函数)。我怀疑您可能正在做这样的事情,因为这是我所知道的将性能降低到您建议的水平的唯一方法。

内存映射文件对您没有帮助。

在您的情况下,一个最大的和重要的改进是,在不将保存到磁盘的情况下处理文件,然后,如果您确实需要存储它们,将它们推送到Queue并在另一个线程中进行验证,通过将它们保存在磁盘上。通过这样做,您将立即获得所需的处理数据,而不会浪费时间将数据保存在磁盘上,但之后也将在磁盘上有一个文件,而不会失去file processor的计算能力。