2012-06-11 129 views
4

我有一系列需要完成的工作;工作之间没有依赖关系。我正在寻找一种能够帮助我将这些工作分配给机器的工具。唯一的限制是每台机器只能一次运行一项作业。我试图最大化吞吐量,因为这些工作不是很平衡。我目前黑客一起使用shell脚本的效率并不高,因为我预先构建了每台计算机的作业队列,并且无法将作业从负载较重的计算机的队列移动到正在等待的计算机,并且已经完成了所有工作。小规模负载均衡

以前的建议已经包括SLURM,这似乎是过度杀伤,甚至更多矫枉过正LoadLeveller。

GNU Parallel看起来像我想要的,但远程机器不会说SSH;有一个自定义的作业启动器(没有排队功能)。我想要的是Gnu Parallel,它可以在工作分派之前立即将机器替换为shell脚本。

因此,简言之:

  • 机器可以接受的作业+目录的列表:最大限度地提高吞吐量。尽可能接近壳体是首选。

最糟糕的情况可以用bash的lockfile破解一些东西,但我觉得好像更好的解决方案必须存在某处。

+0

你有没有考虑使用壳内置作业?类似while#jobs> = maxjobs sleep .1;命令& – technosaurus

回答

2

假设你的工作是在一个文本文件jobs.tab看起来像

/path/to/job1 
/path/to/job2 
... 

创建dispatcher.sh,就像这样

mkfifo /tmp/jobs.fifo 
while true; do 
    read JOB 
    if test -z "$JOB"; then 
    break 
    fi 
    echo -n "Dispatching job $JOB .." 
    echo $JOB >> /tmp/jobs.fifo 
    echo ".. taken!" 
done 
rm /tmp/jobs.fifo 

和运行的

dispatcher.sh < jobs.tab 

一个实例现在创建launcher.sh

while true; do 
    read JOB < /tmp/jobs.fifo 
    if test -z "$JOB"; then 
    break 
    fi 

    #launch job $JOB on machine $0 from your custom launcher 

done 

和运行的launcher.sh每个目标机器一个实例(给机器作为第一个也是唯一一个参数)

+0

看,我知道必须有一个简单的选择。谢谢!我会尽快尝试,但在检查时看起来不错。我只接受这一点。 –

+0

所以在我的机器上,它看起来像在终止时有一些奇怪的边缘情况行为。总的来说,一切正常,但最后发射器都会等待来自FIFO的输入。 就我而言,我已经通过向每个启动器发送一个标记值(“quit”)(检查存在的启动器的进程列表)来解决它。 –

+0

TBH我没有任何检查就没有100%确定'rm/tmp/jobs.fifo',但它在我简单的测试案例中起作用。哨兵是一个优秀和强大的想法。 –

1

GNU并行支持自己的ssh命令。所以这应该工作:

function my_submit { echo On host $1 run command $3; } 
export -f my_submit 
parallel -j1 -S "my_submit server1,my_submit server2" my_command ::: arg1 arg2 
+0

感谢您的支持,它看起来像另一个很好的答案。只是好奇,是否有提交函数的args文档?我在[manpage](http://www.gnu.org/software/parallel/man.html)中找不到它。 –

+0

上面定义了bash函数'submit'。它不在任何手册页中。更改函数'submit'以适应您的需求。我将名称更改为my_submit,强调它是由您定义的。 –

+0

所以我跟着。我从这里得到的理解是,在封面下,而不是执行'ssh server1 ... my_command arg1',而是执行'my_submit server1 ... my_command args'。我很好奇的是第二个参数'...',我可以用它做很酷的事情吗? –