微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

在具有多个cpuS脚本的非常大型的SMP机器上运行数十个同时作业(less于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

分配器将input数据平坦地读出并按顺序分配给FIFO。 (logging1,41,81 …到FIFO1,2,42,82到FIFO2等)分离器的开销很低,可以像文件系统一样快地处理数据。

每个some_program处理其stream并将其写入其输出文件。 但是,没有任何东西控制文件系统看到这些写入的顺序。 写入也非常小,大约10个字节。 脚本“知道”这里有40个数据stream,可以caching20M(或其他)数据块,然后每个数据块依次写入文件系统。 也就是说,应该使用排队写入来最大化写入磁盘的速度。 然而,操作系统只是在40个数据stream中以大约相同的速率看到一堆写入。

实际运行过程中发生的情况是,subprocess得到大量的cpu时间(最高> 80%),然后出现一个刷新过程(10%的cpu),其他所有的cpu都下降到低的cpu(1%),那么它回到更高的速度。 这些停顿一次持续几秒钟。 刷新意味着写入压倒了文件caching。 另外,我认为操作系统和/或底层的RAID控制器可能会在物理磁盘周围不稳定地跳动,这会降低物理磁盘的最终写入速度。 这只是一个猜测,因为很难说出发生了什么事情,因为文件caching(在超过500Gb的RAM的系统中)以及写入和磁盘之间的RAID控制器。

文件调用close()后不立即刷新到磁盘?

Linux世界中是否有与.Net FileSystemWatcher相当的function?

如何调用shell的“文件复制对话框”来报告在Win32中复制的进度?

epoll文件描述符操作

不太确定URI是如何处理文件的绝对path的

是否有一个程序或方法来控制这种types的IO,迫使文件系统写入很好地排队,以最大限度地提高写入速度?

“缓冲区”程序在这里不会有太大的帮助,因为虽然它会将输出stream积累到一个很大的块中,但是不会有一个有序的写入队列,所以有几个可以同时出去。 如果输出stream中的数据速率是不相关的,那么这个问题就不会那么严重了,但在某些情况下,所有数据stream中的数据速率是完全相同的,这意味着缓冲区将同时填满。 这会拖延整个树,直到最后一个被写入,因为任何不能写入输出的进程都不会读取其下一个input,并且会阻塞分离器,因为所有的I / O都是同步的。 缓冲区需要以循环的方式清空,最好是在其中的任何一个完全填满之前清空,尽pipe当数据输出速率超过文件系统写入速率时这是不可避免的。

调整文件系统有几十个参数,其中一些可能会有所帮助。 调度程序从cfq更改为最后期限,因为系统与前者同时locking了几分钟。

单缓冲区; 多个sockets; Linux下的单个系统调用

从Python中的文本文件中读取行(Windows)

获取IO服务时间(svctm),等待时间(等待),在Windows服务器%util

为什么我无法将所有数据从sys.stdin写入Windows中的文件

谁在CreateFile上强制执行dwShareMode? 操作系统还是驱动程序?

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

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

“缓冲区”程序在这里不会有太大帮助,因为虽然它会将输出流累积成一个大块,但是不会有一个有序的写入队列,所以有几个可以同时出去。

你不一定需要大块。 在文件系统的本地块大小或它的一个小整数倍的情况下,这可能是理想的。 例如,可能是4096字节或8192字节的块。

而且,我不明白你为什么认为你现在有一个“有序的写作排队”,或者你为什么相信这样的事情是需要的。

如果输出流中的数据速率是不相关的,那么这个问题就不会那么严重了,但在某些情况下,所有数据流中的数据速率是完全相同的,这意味着缓冲区将同时填满。 这会拖延整个树,直到最后一个被写入,因为任何不能写入输出的进程都不会读取其下一个输入,并且会阻塞分离器,因为所有的I / O都是同步的。

你的分配器正在写入FIFO。 虽然它可能是串行的,但是这并不是“同步的”,因为在分离器可以继续进行之前,数据需要从另一端排出 – 至少,如果写入不超过FIFO的大小,缓冲区。 FIFO缓冲区容量因系统而异,在一些系统上动态调整,并可在某些系统上配置(例如通过fcntl() )。 现代Linux的认缓冲区大小是64kB。

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

我认为这是一个很难解决的问题。 如果其中一个缓冲区备份足够阻塞分离器,那么确保竞争的进程将在太久之前给被阻塞的缓冲区写入机会。 但这也是为什么你不需要巨大的缓冲区 – 你想要从不同的进程交错磁盘I / O相对较好,以尽量保持一切。

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐