在Linux中执行时,我一直在尝试理解下面命令中涉及的执行和内部数据结构和算法。
bzip -dc mybig.bz2 | cut -d ',' -f 1,2,4,5,9,10,12 | sort > output_file
sort
排序而不需要一次输入所有输入吗? mybig.bz2
的大小是20GB,如何排序管理所有中间结果磁盘这么大的文件? 使用重定向和中间文件。
bzip -dc mybig.bz2 > temp1
cut -d ',' -f 1,2,4,5,9,10,12 temp1 > temp2
sort temp2 > output_file
使用管道。
bzip -dc mybig.bz2 | cut -d ',' -f 1,2,4,5,9,10,12 | sort > output_file
有没有更好的方法来使用shell,其中cat
,cut
和sort
并行运行(行缓冲)并且最小的磁盘I / O和cpu周期?
任何帮助高度赞赏。
答案 0 :(得分:0)
使用重定向和中间文件
bzip -dc mybig.bz2 > temp1
cut -d ',' -f 1,2,4,5,9,10,12 temp1 > temp2
sort temp2 > output_file
我们假设mybig.bz2为1 GB,未压缩版本为10 GB。以上将是:
总磁盘I / O为1 + 10 + 10 + 10 + 10 + 10 + 10 + 10 = 71 GB。
使用管道
bzip -dc mybig.bz2 | cut -d ',' -f 1,2,4,5,9,10,12 | sort > output_file
在这里:
总磁盘I / O为1 + 10 + 10 + 10 = 31 GB。
使用管道不会浪费任何东西。相反,如果bzip2与排序速度相同,则可以保持2个CPU并行运行。较新版本的排序也支持' - parallel = N'在多个CPU上分发排序。
如果排序的数据压缩得很好,您还可以使用--compress-program=PROG
来压缩临时文件。如果您的CPU无论如何都处于空闲状态,这将非常有用。根据您闲置的CPU数量,您可以使用' pzstd',' pigz',' pbzip2',' pxz'。它们具有不同的压缩程度(从低到高)。
这样您就可以将磁盘I / O从31 GB降低到1 + 1 + 1 + 10.
管道中的中间结果不存储在任何地方。相反,它会在写入后立即读取。两个进程之间只有一个小缓冲区(通常大约为4-128 KB)。当缓冲区已满时,写入过程会阻塞,直到读取过程从缓冲区读取内容。这种技术可以在1 GB RAM和100 GB磁盘的系统上处理1 TB数据 - 只要数据在存储在磁盘上时就被压缩。