25

这是我面临的问题:

  • 我正在处理一个大小约为 100G 的文本文件。
  • 我试图通过将文件拆分为数百个较小的文件并并行处理它们来改善运行时间。
  • 最后,我将生成的文件按顺序重新组合在一起。

文件读/写时间本身需要几个小时,所以我想找到一种方法来改进以下内容:

cat file1 file2 file3 ... fileN >> newBigFile
  1. 这需要双倍的磁盘空间file1……fileN占用 100G,然后再newBigFile占用 100Gb,然后file1……fileN被删除。

  2. 数据已经在file1...fileN中,cat >>当我真正需要的只是数百个文件重新出现为 1 个文件时,会产生读写时间...

4

8 回答 8

14

如果您不需要随机访问最终的大文件(即,您只需从头到尾通读一遍),您可以将数百个中间文件显示为一个。你通常会做的地方

$ consume big-file.txt

而是做

$ consume <(cat file1 file2 ... fileN)

这使用 Unix进程替换,有时也称为“匿名命名管道”。

您还可以通过拆分输入并同时进行处理来节省时间和空间;GNU Parallel有一个--pipe 开关可以做到这一点。它还可以将输出重新组合到一个大文件中,从而可能使用更少的暂存空间,因为它只需要一次在磁盘上保留多个核心片段。如果您实际上同时运行数百个进程,Parallel 将通过让您调整机器的并行量来大大提高您的效率。我强烈推荐它。

于 2011-06-27T19:03:57.617 回答
7

将文件重新连接在一起时,您可以删除附加的小文件:

for file in file1 file2 file3 ... fileN; do
  cat "$file" >> bigFile && rm "$file"
done

这将避免需要双倍的空间。

没有其他方法可以神奇地使文件神奇地连接起来。文件系统 API 根本没有这样做的功能。

于 2010-11-01T21:24:52.813 回答
5

也许dd会更快,因为您不必在 cat 和 shell 之间传递东西。就像是:

mv file1 newBigFile
dd if=file2 of=newBigFile seek=$(stat -c %s newBigFile)
于 2010-11-01T19:30:16.680 回答
4

我真正需要的只是让数百个文件重新出现为 1 个文件......

在文件系统级别以这种方式连接文件是不切实际的,因为文本文件通常不会完全填充磁盘块,因此必须向上移动后续文件中的数据以填充间隙,从而导致反正一堆读/写。

于 2010-11-01T19:41:43.063 回答
4

您是否可以简单地不拆分文件?而是通过在每个并行工作人员中设置文件指针来分块处理文件。如果需要以面向行的方式处理文件,这会变得更加棘手,但仍然可以完成。每个工作人员都需要了解,它必须首先逐字节查找下一个换行符 +1,而不是从您给它的偏移量开始。每个工作人员还必须了解,它不会处理您给它的设定字节数,而是必须在分配给它处理的设定字节数之后处理第一个换行符。

文件指针的实际分配和设置非常简单。如果有 n 个 worker,每个 worker 处理 n/file size 个字节,文件指针从 worker number * n/file_size 开始。

有什么理由这样的计划是不够的吗?

于 2010-11-01T21:18:19.633 回答
4

我相信这是对同一文件夹中包含的所有文件进行分类的最快方法:

$ ls [path to folder] | while read p; do cat $p; done
于 2016-09-02T17:02:19.200 回答
3

快速但不是免费的解决方案?获取基于 SSD 驱动器或闪存 PCIe 的存储。如果这是必须定期完成的事情,那么提高磁盘 IO 速度将是您可以获得的最具成本效益和最快的加速。

于 2010-11-01T19:27:42.253 回答
2

有太多并发这样的事情。

这样做的更好方法是在所需范围内对文件使用随机访问读取,并且从不实际拆分它并且仅处理文件数作为机器中的物理 CPU/核心数。除非这也使 IOPS 淹没了磁盘,否则您应该减少直到磁盘不是瓶颈为止。

您对所有幼稚的拆分/复制/删除所做的任何一种方式都会产生大量的 IOPS,并且无法绕过它的物理特性。

一个透明的解决方案可能比值得做的更多,除非这是一个持续的日常问题/问题,是编写一个自定义 FUSE 文件系统,将单个文件表示为多个文件。有很多关于将存档文件内容作为单个文件处理的示例,这些示例将向您展示如何执行此操作的基础知识。

于 2011-06-27T19:16:43.883 回答