【发布时间】:2019-01-24 15:48:47
【问题描述】:
我想提高将几个通常很小的文件写入网络附加卷的软件的吞吐量。
卷限制为 100 IOPS 和 80 MB/s 的带宽。
目前我已达到 100 IOPS,但带宽与可达到的 80 MB/s 相差甚远,约为 4 MB/s,但甚至更低。
我认为主要问题是我们发出了很多小请求,这些小请求使 IOPS 饱和,但带宽几乎没有被利用。
该软件是用 C 语言编写的,我几乎可以控制一切,直到实际的 write 系统调用。
目前架构是多线程的,有几个线程作为“假脱机程序”工作并进行同步write 调用,每个线程用于不同的文件。
假设我们有文件a、b 和c 和线程t1、t2 和t3。
t1 将打开a 并在循环中调用write(fd_a, buff_a, 1024) 之类的东西,t2 (write(fd_b, buff_b, 1024)) 和t3 (write(fd_c, buff_c, 1024)) 也是如此。
每个文件都是一个新文件,所以它是在第一次写入时创建的。
我认为问题在于操作系统发出的请求(在 Linux IO 调度程序合并之后)非常小,每个大约 10/20 个块(5/10 KB)。
我认为解决问题的唯一方法是提出更大的请求,但每个文件都很小,所以我不太确定最好的方法是什么。
一个可能的想法是发出单个write 请求而不是多个请求的循环,因此查找文件有多大,分配足够的内存,填充缓冲区并最终执行单个write。
另一个想法可能是切换如此异步 io,但我不明白在这种情况下会有什么优势。
你还有什么建议吗?
【问题讨论】:
-
如果这是一个硬盘驱动器(看起来像一个非常低规格的慢速硬盘驱动器),你就处于硬件的极限。小请求在操作之间有一个寻道时间。这将限制您的带宽。对于这种类型的工作负载,4MB/s 实际上是一个不错的结果。
-
这些小文件是否相互关联?将它们的内容组合成更少的大文件文件是否有意义,可能是类似 tar 的格式?
-
这似乎是多余的,但我想在循环中没有做任何其他事情?
-
@drescherjm,是的,我们在非常商品化的硬件上运行,4MB/s 是实际架构达到的上限,通常它更慢。
-
@Siscia 你不能做什么?改代码?或者获得更快的存储系统?如果您需要更好的吞吐量,您必须至少完成其中一项。因为你现在的设计需要太多的 IO 操作来写入少量的数据。您当前的设计可能需要 4-5 次 IO 操作来写入少量千字节。设计良好的快速存储系统每次 IO 操作可以移动 1 兆字节或更多。您在问,“我怎样才能将我的Yugo 变成赛车并赢得 F1 比赛?”答案是你不能。
标签: c linux io filesystems