正确的xargs并行用法


9

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

find ./data -name "*.json" -print0 |
  xargs -0 -I{} -P 40 python Convert.py {} > log.txt

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

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


6
您最有可能被I / O击中:系统无法足够快地读取文件。尝试启动40多个:这样,如果某些进程必须等待I / O,就可以了。
Ole Tange 2015年

脚本执行哪种处理?是否涉及任何数据库/网络/ IO?它运行多长时间?
福克斯

1
我第二个@OleTange。如果您运行的进程数与内核数相同,并且任务受IO限制,则这是预期的行为。首先,内核将在IO上等待其任务(睡眠),然后将进行处理,然后重复执行。如果添加更多进程,那么当前不在物理内核上运行的其他进程将启动并行IO操作,这将在完成后消除或至少减少内核上的睡眠时间。
PSkocik

1-您是否启用了超线程?2-在您那里,每次对convert.py的调用实际上都会覆盖log.txt ...不确定这是否是预期的行为。
Bichoy

xargs -P并且>由于半线问题gnu.org/software/parallel/而开放了比赛条件。使用GNU Parallel不会有这个问题。
奥莱·丹吉

Answers:


4

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

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

find ./data -name "*.json" -print0 |
  xargs -0 -L1000 -P 40 python Convert.py

这并不是说python是一种不好的/慢速的语言。它只是没有针对启动时间进行优化。您将看到任何基于虚拟机或解释型语言的内容。例如,Java会更糟。如果您的程序是用C编写的,则启动一个单独的操作系统进程来处理每个文件仍然会产生一定的开销,但是花费会更少。

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


1

因此,首先,请考虑以下约束:

每个工作受到什么限制?如果它的I / O可以或许侥幸每个CPU核心了多份工作,直到你打的I / O的限制,但如果它的CPU密集型的,它会比无意义的运行更多的就业机会更糟糕的同时比你的CPU核心。

我对这些事情的理解是,GNU Parallel将使您更好地控制作业队列等。

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


0

正如其他人所说,请检查您是否受I / O约束。另外,xargs的手册页建议-n与配合使用-P,但不要提及Convert.py并行运行的进程数。

作为建议,如果您受I / O约束,则可以尝试使用SSD块设备,或尝试在tmpfs中进行处理(当然,在这种情况下,您应该检查足够的内存,避免由于tmpfs而导致交换)压力(我认为),以及首先将数据复制到其中的开销)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.