限制管道大小并写入临时文件作为后备

限制管道大小并写入临时文件作为后备

我有一个有点棘手的问题。我想将一个命令的结果通过管道传输到另一个命令,但由于我使用的系统内存有限,我想确保管道不会占用太多内存。但我不想让它在达到极限时中断,只需切换到使用磁盘作为临时文件即可。

用例如下。我使用 curl 或 wget 下载了一个大文件。我将结果通过管道传输到另一个程序(实际上是传输到命名管道,但该命名管道会立即提供给另一个命令)。如果一切顺利,第二个命令能够比 curl 输出输入的速度更快(下载比第二个命令的处理速度慢)。

但有时事情会出错,第二个命令需要一些时间才能开始消耗它。最终可能会这样,但由于第二个命令需要一些 RAM,而我的资源有限,所以如果管道开始使用超过 200 MB 的 RAM,我想切换到写入磁盘。

第二个命令的启动时间甚至可能比下载文件所需的时间还要长。在这种情况下,下载的文件应该完全写入磁盘,以便第二个进程稍后使用它。

这么愚蠢的问题有解决办法吗?

答案1

您的问题与另一个问题类似:在管道之间使用磁盘支持的缓冲区,其中答案是mbuffer -T /path/to/file。不同之处在于您组合缓冲区的想法:

如果管道开始使用超过 200 MB 的 RAM,我想切换到写入磁盘。

像这样连接两个缓冲区:

feeder | mbuffer -T /path/to/file -m 2G | mbuffer -m 200M | consumer

数据会尽可能地流动,因此 200 MiB 内存缓冲区将首先被填满(如果有的话)。只有这样,2 GiB 磁盘缓冲区才会开始保存数据。

笔记:

  • 似乎文件一开始就被分配了完整大小。如果设备上没有剩余空间,整个管道将提前失败。不过,这会带来一些初始延迟。

  • 在我的测试中,mbuffer即使第二个立即从管道读取,第一个也会写入文件。我认为第一个可能在不接触文件的情况下传递数据;但事实并非如此,即使磁盘缓冲区根本没有使用,整个管道也会受到磁盘速度的限制。

相关内容