能否通过并行处理找到更好的 UNIX 版本?

能否通过并行处理找到更好的 UNIX 版本?

unixfind(1)实用程序非常有用,它允许我针对符合特定规范的许多文件执行操作,例如

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

上述操作可能会在特定目录下的每个 XML 文件上运行脚本或工具。

假设我的脚本/程序占用大量 CPU 时间,并且我有 8 个处理器。一次最多处理 8 个文件就好了。

GNU make 允许使用-j标志进行并行作业处理,但find似乎没有这样的功能。有没有其他通用的作业调度方法可以解决这个问题?

答案1

xargs使用-P选项(进程数)。假设我想在 4-cpu 机器上压缩目录中的所有日志文件:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2

您还可以说-n <number>每个进程的最大工作单元数。假设我有 2500 个文件,我说:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2

这将启动 4 个bzip2进程,每个进程处理 500 个文件,然后当第一个进程完成时,将启动另一个进程处理最后 500 个文件。

不确定为什么以前的答案使用xargs make,那里有两个并行引擎!

答案2

GNU并行也可以帮忙。

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

请注意,如果没有参数-j8,则parallel默认为您机器上的核心数:-)

答案3

无需“修复” find——利用make其自身来处理并行性。

让你的进程创建一个日志文件或其他输出文件,然后使用如下 Makefile:

.SUFFIXES:  .xml .out

.xml.out:
        java -jar ProcessFile.jar $< 1> $@

并调用如下代码:

find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8

更好的是,如果您确保仅在 Java 进程成功完成后才创建输出文件,您可以利用make依赖关系处理来确保下一次只有未处理的文件完成。

答案4

所有建议都使执行并行运行,但如果文件树足够大,瓶颈可能就在于 find 本身。我的一位同事写道洛卡作为并行搜索,当您的文件系统可以并行扫描时,它非常有用。如果您的文件系统位于单个 HDD 上,它可能没有帮助,但如果它是 raid 设备、SSD 或更好的分布式文件系统,它将大有帮助。

locar 将在多个目录上并行执行文件扫描,因此您将更快地获得文件列表,然后还可以将其与 xargs 或 parallel 结合起来并行运行。

相关内容