提高在C

时间:2018-08-17 15:01:16

标签: c linux io filesystems

我想提高将几个通常很小的文件写入网络附加卷的软件的吞吐量。

该卷限制为100 IOPS和80 MB / s的带宽。

此刻我达到了100 IOPS,但带宽与可达到的80 MB / s距离非常远,约4 MB / s,甚至更低。

我相信主要的问题是我们提出了许多小请求,这些小请求使IOPS饱和,但是带宽几乎未被利用。

该软件是用C语言编写的,我几乎可以控制一切,直到实际的write系统调用为止。

目前,该体系结构是多线程的,其中多个线程充当“假脱机程序”并进行同步write调用,每个线程用于一个不同的文件。

因此,假设我们有文件abc以及线程t1t2t3

t1将打开a并循环调用类似write(fd_a, buff_a, 1024)的内容,而t2write(fd_b, buff_b, 1024))和t3的作用相同(write(fd_c, buff_c, 1024)

每个文件都是一个新文件,因此它是在第一次写入时创建的。

我相信问题在于,操作系统发出的请求(在Linux IO调度程序合并之后)非常小,每个请求的顺序为10/20块(5/10 KB)。

我认为解决此问题的唯一方法是发出更大的请求,但是每个文件都很小,因此我不确定什么是最好的转发方式。

一个可能的想法可能是发出一个write请求,而不是几个请求的循环,因此查找文件有多大,分配足够的内存,填充缓冲区并最终执行一个{{1} }。

另一个想法可能是切换异步io,但是我不了解这种情况下的优势。

您还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

您可以将所有文件放入内存中的tar归档文件中。然后,您可以将tar存档作为一个大请求写入,然后将tar存档解压缩为一个单独的过程,从而释放编写程序。

这是一个更具创意的想法。首先,根据文件的保存位置(可能是目录)将文件分组。然后在组中找到最大的文件。填充其他文件的内容,以使每个文件的大小相同。然后将文件彼此追加,这样便有了一个大文件。发送该写请求。因此,现在我们编写了一个大文件,其中包含许多大小相等的较小文件。因此,请使用linux split命令将文件拆分为多个原始文件(https://kb.iu.edu/d/afar)。这可能有效,但是您必须在文件末尾添加空白。

编辑:必须注意,这些解决方案不可扩展。长期的解决方案将是@AndrewHenle在评论中建议的。