正确的 xargs 并行使用

Yan*_*Zhu 10 xargs parallelism

我正在使用xargs一个 python 脚本来处理大约 3000 万个小文件。我希望用来xargs并行化这个过程。我使用的命令是:

find ./data -name "*.json" -print0 |
  xargs -0 -I{} -P 40 python Convert.py {} > log.txt
Run Code Online (Sandbox Code Playgroud)

基本上,Convert.py会读入一个小的json文件(4kb),做一些处理并写入另一个 4kb 文件。我在具有 40 个 CPU 内核的服务器上运行。并且此服务器上没有运行其他 CPU 密集型进程。

通过监控 htop(顺便说一句,有没有其他好的方法来监控 CPU 性能?),我发现它-P 40没有预期的那么快。有时所有内核会冻结并在 3-4 秒内几乎降至零,然后恢复到 60-70%。然后我尝试将并行进程的数量减少到-P 20-30,但它仍然不是很快。理想的行为应该是线性加速。对 xargs 的并行使用有什么建议吗?

Jam*_*ven 6

我愿意打赌你的问题是python。你没有说对每个文件进行什么样的处理,但假设你只是对数据进行内存中处理,那么运行时间将由启动 3000 万个 python 虚拟机(解释器)来主导。

如果您可以重构您的 python 程序以获取文件列表,而不是仅一个文件,那么您将获得性能上的巨大提升。然后您仍然可以使用 xargs 来进一步提高性能。例如40个进程,每个进程处理1000个文件:

find ./data -name "*.json" -print0 |
  xargs -0 -L1000 -P 40 python Convert.py
Run Code Online (Sandbox Code Playgroud)

这并不是说 python 是一种糟糕/缓慢的语言;而是说它是一种糟糕的/缓慢的语言。它只是没有针对启动时间进行优化。您将在任何基于虚拟机的语言或解释语言中看到这一点。例如,Java 的情况会更糟。如果你的程序是用 C 语言编写的,启动一个单独的操作系统进程来处理每个文件仍然会产生成本,但会少得多。

从那里您可以尝试看看-P是否可以提高一点速度,也许可以通过增加进程数量来在读取/写入数据时利用空闲处理器。


小智 1

因此,首先,考虑约束:

每项工作的限制是什么?如果是 I/O,您可能可以在每个 CPU 核心上执行多个作业,直到达到 I/O 的限制,但如果是 CPU 密集型,则比毫无意义地同时运行比 CPU 核心更多的作业更糟糕。

我对这些事情的理解是,GNU Parallel可以让你更好地控制作业队列等。

有关两者有何不同的更详细说明,请参阅GNU parallel vs & (我的意思是背景) vs xargs -P 。