是否tar | gpg | bzip2使用更多的内存比单独做每一步?

我有一堆我经常需要tar的文件,用gpgencryption,然后压缩。 这是在一个Linus VPS服务器上,所以内存比执行速度(我真的不关心)更重要。

如果我像一个命令(tar | gpg | bzip2> output.tar.gpg.bzip2)那样执行这三个步骤会消耗比先调用tar更多的内存,然后调用gpg,然后调用bzip2?

这些文件可能相当大(数百兆字节/千兆字节)

同时运行的程序越多,需要的内存就越多。 但是这是一个权衡,使用pipe道而不是单独运行每个程序往往需要更less的磁盘空间。 您只需要存储初始input和最终输出。 如果您通过ssh或其他类似的东西来存储其他地方的数据,您甚至可能不需要超出input文件的初始磁盘空间。 使用pipe道的另一个特性是数据在任何阶段的处理都不会比pipe道中最慢的阶段更快。

GnuPG使用的OpenPGP格式本身支持压缩。 这发生在encryption之前,所以它比后encryption压缩更安全,效率更高。 此外,它将在解密时自动检测,因此您不必担心将其添加到pipe道中。 它可能需要比运行一个单独的压缩程序更less的内存。 GnuPG支持Zip,Zlib(Gzip)和Bzip2压缩。

当你这样做的时候( tar | gpg | bzip2 > output.tar.gpg.bzip2 ),你是pipe道命令,这意味着你正在同时运行所有的命令,并把每个命令的输出redirect到下面命令的input中直到你redirect到文件的最后一个输出)。 所以tar输出到gpginput输出到bzip2input,最后输出到文件中。

所以,当你使用更多的内存时,因为你正在同时运行所有的命令。 你也使用更多的处理能力,因为gpgbzip2是两个cpu饥饿的程序。

你应该检查bzip2是否做了一些值大小的事情,pgp数据最终应该看起来像一个(完全)随机stream,因此不应该是可压缩的。

所有这些命令: tarbzip2gpg以类似于stream的方式工作的:它们需要大量数据(比如说一兆字节),将其转换并推送到下一个阶段。 之后,RAM被重用来处理另一块数据。 所以,即使你有一个TB的数据处理,它将被逐一处理。

现在,当你自己调用tar时,tar将以这种方式工作:从磁盘读取一个数据块,将其包含一些归档所需的头文件,将其推送到磁盘并忘记它。 然后再次。 然后再次。 在这个过程中,你永远不会需要在RAM中的一个以上的数据块。 我不知道将有多大的缓冲区,但它可能只有几兆字节。 所以你只需要几兆的RAM就可以工作。

gpgbzip2以同样的方式工作。 gpg需要一小块数据,encryption它并推进 – 全部在一个循环中。 bzip2需要一小块数据,压缩它并推进 – 全部在一个循环中。

如果您不使用stream水线来调用这些命令,您将需要更less的RAM:您将需要在RAM中同时只保留一个数据块。 使用pipe道,数据块将从一个命令传递到另一个命令,将其保存在RAM中:您将需要几个数据块:一个用于tar ,一个用于gpg ,一个用于bzip2 。 所以几兆字节。 您将不需要RAM一次存储所有数据。

通过stream水线,您实际上可以获得另一个好处:速度。 您不需要在磁盘上存储临时数据。 数据块从tar传递到bzip2 ,从bzip2传递到gpg只使用RAM。 比较:3GB的数据,tar文件中的3GB数据,tar.bzip2文件中的1GB数据,tar.bzip2.gpg文件中的1GB数据。 即使不同时存储它们(删除进程中的源文件),仍然需要向磁盘写入和读取4GB以上的数据。 而且VPS在磁盘操作上通常很慢,所以pipe道可以节省很多时间。

(注意:这个解释是简单的,所有这些命令都会在RAM中保留一些额外的数据,但是这并不重要,而且你可以经常改变特定命令中缓冲区的大小。