并行有效地运行多个作业

OS:Cent-OS

我有30,000个工作(或脚本)运行。 每个工作需要3-5分钟。 我有48 CPUs(nproc = 48) 。 我可以使用40 CPUs to run 40 Jobs并行40 CPUs to run 40 Jobs 。 请build议一些脚本或工具通过并行运行每个40个作业来处理30,000个作业。

我做了什么:

  • 我创build了40个不同的文件夹,并通过为每个目录创build一个shell脚本来并行执行作业。

  • 我想知道下一次处理这类工作的更好方法。

Solutions Collecting From Web of "并行有效地运行多个作业"

正如Mark Setchell所说:GNU并行。

 find scripts/ -type f | parallel 

如果你坚持让8个CPU空闲:

 find scripts/ -type f | parallel -j-8 

但通常情况下,使用nice效率更高,因为在没有其他人需要的时候,它可以提供所有48个核心。

 find scripts/ -type f | nice -n 15 parallel 

了解更多:

  • 观看介绍视频快速介绍: https : //www.youtube.com/playlist?list=PL284C9FF2488BC6D1
  • 浏览教程(man parallel_tutorial)。 你命令爱你。

我已经使用REDIS来做这种事情 – 安装起来非常简单,而且CLI很容易使用。

我主要使用LPUSH将所有作业推送到REDIS和BLPOP的“队列”中,以阻止从队列中删除作业。 所以,你需要在启动时启动30,000个作业(或脚本名称或参数),然后在后台启动40个进程(每个CPU 1个进程),每个进程将循环执行BLPOP以获得工作,运行并执行下一个。

您可以添加复杂层次以在另一个“队列”中记录完成的作业。

这是一个小小的演示:

将3个作业推送到称为作业的队列:

 ./redis-server & # start REDIS server in background ./redis-cli # start REDIS command line interface redis 127.0.0.1:6379> lpush jobs "job1" (integer) 1 redis 127.0.0.1:6379> lpush jobs "job2" (integer) 2 redis 127.0.0.1:6379> lpush jobs "job3" (integer) 3 

查看队列中有多少个工作:

 redis 127.0.0.1:6379> llen jobs (integer) 3 

等待无限超时工作

 redis 127.0.0.1:6379> brpop jobs 0 1) "jobs" 2) "job1" redis 127.0.0.1:6379> brpop jobs 0 1) "jobs" 2) "job2" redis 127.0.0.1:6379> brpop jobs 0 1) "jobs" 2) "job3" 

由于队列中没有工作,最后一个将等待很长时间:

 redis 127.0.0.1:6379> brpop jobs 0 

当然,这是很容易的脚本:

把3万个工作放在队列中:

 for i=0;i<30000;i++ do echo "lpush jobs job$i" | redis-cli done 

以下是如何检查进度:

 echo "llen jobs" | redis-cli (integer) 30000 

你可以像这样开始40个工作:

 for i=0;i<40;i++ ./Keep1ProcessorBusy $i & done 

然后Keep1ProcessorBusy会是这样的:

 while(1) do job=$(echo brpop jobs 0 | redis_cli) # Set processor affinity here too if you want to force it, use $1 parameter we were called with do $job done 

作为一个完全不同的选项,你可以看看这里的 GNU Parallel 。 还要记住,你可以通过使用-P选项的xargs来运行find的输出来平行化东西。

只要执行这些脚本,Linux将在内部正确地在可用的CPU之间分配这些任务。 这是在Linux任务调度器上。 但是,如果您需要,也可以使用taskset在特定的CPU上执行任务(请参阅man taskset )。 你可以从一个脚本来执行你的30K任务。 记住在这个手动的方式,确保你在做什么。