排队写入Linux上的文件系统?

时间:2015-05-15 17:47:29

标签: linux io

在一个非常大的SMP机器上运行了许多CPUS脚本,并运行了数十个同时的作业(少于CPU的数量),如下所示:

some_program -in FIFO1 >OUTPUT1 2>s_p1.log </dev/null &
some_program -in FIFO2 >OUTPUT2 2>s_p2.log </dev/null &
...
some_program -in FIFO40 >OUTPUT40 2>s_p40.log </dev/null &
splitter_program -in real_input.dat -out FIFO1,FIFO2...FIFO40

分离器将输入数据平整读出并按顺序将其分配给FIFO。 (记录1,41,81 ...到FIFO1; 2,42,82到FIFO2等)分路器的开销很低,并且可以像文件系统提供的那样快速处理数据。

每个some_program处理其流并将其写入其输出文件。但是,没有什么可以控制文件系统看到这些写入的顺序。写入也非常小,大约10个字节。脚本“知道”这里有40个流,它们可以在20M(或其他)块中缓冲,然后每个块按顺序写入文件系统。也就是说,应该使用排队写入来最大化磁盘的写入速度。然而,操作系统只能在40个流中的每一个上以大约相同的速率看到一堆写入。

在运行期间实际发生的事情是子进程获得大量CPU时间(在顶部,> 80%),然后出现刷新进程(10%CPU),并且所有其他进程都降低到低CPU( 1%),然后它回到更高的速度。这些暂停一次持续几秒钟。刷新意味着写入压倒了文件缓存。另外我认为操作系统和/或底层RAID控制器可能会不稳定地反弹物理磁盘磁头,从而降低了物理磁盘的最终写入速度。这只是一个猜测,因为很难说究竟发生了什么,因为存在文件缓存(在具有超过500Gb RAM的系统中)和写入与磁盘之间的RAID控制器。

是否存在控制此类IO的程序或方法,强制文件系统写入队列以最大限度地提高写入速度?

“缓冲”程序在这里没有多大帮助,因为虽然它会将输出流累积到一个大块中,但是不会有一个有序排队的写入,所以有几个可以同时出去。如果输出流中的数据速率不相关,则这不是问题,但在某些情况下,所有流中的数据速率完全相同,这意味着缓冲区将同时填充。这将使整个树停止,直到写入最后一个树,因为任何无法写入输出的进程都不会读取其下一个输入,这会使分离器停止,因为所有I / O都是同步的。缓冲区需要以循环方式清空,最好在它们中的任何一个完全填满之前清空,尽管在数据输出速率超过文件系统写入速率时可能无法避免。

有许多用于调整文件系统的参数,其中一些可能会有所帮助。调度程序从cfq更改为截止日期,因为系统与前者一起锁定了几分钟。

2 个答案:

答案 0 :(得分:0)

如果问题是纯粹的I / O带宽,那么缓冲不会解决任何问题。在这种情况下,您需要缩小数据或将其发送到更高带宽的接收器,以改善和平衡性能。一种方法是减少并行作业的数量,正如@thatotherguy所说。

但实际上,问题在于不同I / O操作的数量而不是整体数据量,那么缓冲可能是一个可行的解决方案。我不熟悉你提到的buffer程序,但我想它的名字就是它的名字。但是,我并不完全赞同你的缓冲评论:

  

&#34;缓冲区&#34;程序在这里没有多大帮助,因为虽然它会将输出流累积到一个大块中,但不会对这些写入进行有序排队,因此有几个可能同时出现。

您不一定需要块。以文件系统的本机块大小或其小的整数倍来块化可能是理想的。例如,这可能是4096或8192字节的块。

此外,我不明白为什么你认为你有一个&#34;有序排队的写作&#34;现在,或者为什么你确信需要这样的东西。

  

如果输出流中的数据速率不相关,则这不是问题,但在某些情况下,所有流中的数据速率完全相同,这意味着缓冲区将同时填充。这将使整个树停止,直到写入最后一个树,因为任何无法写入输出的进程都不会读取其下一个输入,这会使分离器停止,因为所有I / O都是同步的。

您的分离器正在写入FIFO。虽然它可以连续地这样做,但不是&#34;同步&#34;在分离器可以继续之前,数据需要从另一端排出的意义上 - 至少,如果写入不超过FIFO的大小,则不是这样。缓冲区。 FIFO缓冲容量因系统而异,在某些系统上动态适应,并且在某些系统上是可配置的(例如,通过fcntl())。现代Linux上的默认缓冲区大小为64kB。

  

缓冲区需要以循环方式清空,最好在它们中的任何一个完全填满之前清空,尽管在数据输出速率超过文件系统写入速率时可能无法避免。

我认为这是一个几乎可以解决的问题。如果其中一个缓冲区备份足以阻塞拆分器,则可确保竞争进程在不久之前为阻塞缓冲区提供写入的机会。但这也是你不想要大量缓冲区的原因 - 你想要从不同的进程中交错磁盘I / O,以保证一切顺利。

外部缓冲程序的替代方法是修改进程以执行内部缓冲。这可能是一个优势,因为它从混合中移除了一整套管道(到外部缓冲程序),并且它减轻了机器上的过程负载。这确实意味着修改你的工作处理程序,所以也许最好从外部缓冲开始看看它有多好。

答案 1 :(得分:0)

如果问题是您的40个流都具有高数据速率,并且您的RAID控制器无法足够快地写入物理磁盘,那么您需要重新设计磁盘系统。基本上,将其划分为40个RAID-1镜像,并将一个文件写入每个镜像集。这使得每个流的写入顺序,但需要80个磁盘。

如果数据速率不是问题,那么您需要添加更多缓冲。您可能需要一对线程。一个线程将数据收集到内存缓冲区,另一个线程将其写入数据文件和fsync()它。要使磁盘写入顺序,它应该每次fsync一个输出文件。这应该导致写入大小的连续块,无论你的缓冲区大小是多少。可能是8 MB?