我可以通过 ssh 连接到具有 64 个内核的远程计算机。假设我需要在这台机器上并行运行 640 个 shell 脚本。我该怎么做呢?
我可以看到将 640 个脚本分为 64 组,每组 10 个脚本。然后我将如何运行这些组中的每一个在平行下,即每个可用核心上都有一个组。
是否有以下形式的脚本
./script_A &
./script_B &
./script_C &
...
其中script_A
对应于第一组、script_B
第二组等就足够了?
在一个核心上运行的一组内的脚本可以顺序运行,但我希望这些组在所有核心上并行运行。
答案1
这看起来像是 gnu parallel 的工作:
parallel bash -c ::: script_*
优点是您不必按核心对脚本进行分组,parallel
我们会为您做这件事。
当然,如果您不想在脚本运行时托管 SSH 会话,您应该使用nohup
或screen
答案2
只要您不需要监视输出,并且您可以在脚本运行期间将 ssh 会话保持打开状态,那么这种方法就可以工作。如果其中任何一个不正确,我建议使用screen
多个选项卡。你可以做类似的事情
screen
for script in script_A script_B script_C; do
screen -t "$script" ./$script
done;
答案3
要启动和管理大量脚本作业,您将需要某种管理软件来控制资源使用(CPU、内存、优先级)、查看作业状态(等待、挂起、运行、完成)。
网格引擎就是为此而构建的,例如,Sun Grid Engine (http://wiki.gridengine.info/wiki/index.php/Main_Page)或开放网格调度程序(http://gridscheduler.sourceforge.net/)。在开始之前,您确实需要管理员为您安装适当的软件。管理员可能很乐意这样做,而不是看到数百个进程在计算机上运行,并且无法控制它们。
一般来说,admin定义了一台机器可以分为多少个slot,你向队列提交一个作业并指定该作业要消耗多少个slot,Grid Engine会监控系统整体使用情况,并根据情况运行作业由管理员定义的排队策略。例如,不能同时运行超过 x 个作业,等等。其余作业将在队列中处于等待状态,并在较早的作业完成后释放。
答案4
我曾多次这样做过,通常只是编写自己的脚本来通过作业控制来完成这项工作。一般来说,如果您有要在文件中运行的所有脚本的名称,则解决方案如下所示:
#!/bin/bash
scripts=$(cat scriptfiles.txt)
declare -i NUM=0
declare -i MAX_PROCS=30
for script in "$scripts"
do
NUM=$((NUM+1))
ssh remote.host.ip "${script}" > ${script}.log 2>&1 &
if [ $NUM -ge $MAX_PROCS ];then
echo "Waiting for $NUM processes to finish."
wait
NUM=0
fi
done
echo "Waiting for final $NUM processes to finish."
wait
exit
这是蛮力,但有效。另外,您不需要将任何额外的软件(例如并行)添加到您的系统中。
一个大问题是 wait 命令将等待最慢的脚本完成,这可能会浪费时间。我已经创建了脚本来处理这种情况,但正如您可以想象的那样,它们会变得更加复杂。如果所有脚本的运行时间大致相同,那么这种方法效果很好。
另一个问题是您可能必须调整 MAX_PROCS 才能确定最佳性能。
当然,ssh 连接的数量可能会变得难以处理。在这种情况下,只需将此脚本移至远程主机并更改“ssh...”行以直接运行脚本。