Amazon ec2 使用并行工具在PBS中运行百万个列表
我有一个巨大的(几百万)作业包含列表,希望运行java编写的工具来执行功能比较。此工具在中完成计算Amazon ec2 使用并行工具在PBS中运行百万个列表,amazon-ec2,parallel-processing,openmpi,gnu-parallel,pbs,Amazon Ec2,Parallel Processing,Openmpi,Gnu Parallel,Pbs,我有一个巨大的(几百万)作业包含列表,希望运行java编写的工具来执行功能比较。此工具在中完成计算 real 0m0.179s user 0m0.005s sys 0m0.000s sec 在GNU并行环境下,使用pbs torque scheduler运行5个节点(每个节点都有72个CPU),该工具运行良好并产生结果,但当我为每个节点设置72个作业时,它应该一次运行72 x 5个作业,但我只能看到它运行25-35个作业! 检查每个节点上的cpu利用率也会显示低利用率 我希望一次运
real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
在GNU并行环境下,使用pbs torque scheduler运行5个节点(每个节点都有72个CPU),该工具运行良好并产生结果,但当我为每个节点设置72个作业时,它应该一次运行72 x 5个作业,但我只能看到它运行25-35个作业!
检查每个节点上的cpu利用率也会显示低利用率
我希望一次运行72 X 5个或更多作业,并利用所有可用源(72 X 5 CPU)生成结果
正如我提到的,要运行约2亿个作业,我希望通过使用/增加节点/CPU的数量来更快地完成它(1-2小时)
当前代码、输入和作业状态:
example.lst(大约有3亿行)
cat job_script.sh
#!/bin/bash
#PBS -l nodes=5:ppn=72
#PBS -N job01
#PBS -j oe
#work dir
export WDIR=/shared/data/work_dir
cd $WDIR;
# use available 72 cpu in each node
export JOBS_PER_NODE=72
#gnu parallel command
parallelrun="parallel -j $JOBS_PER_NODE --slf $PBS_NODEFILE --wd $WDIR --joblog process.log --resume"
$parallelrun -a example.lst sh run_script.sh {}
#!/bin/bash
# parallel command options
i=$1
data=/shared/TF_data
# create tmp dir and work in
TMP_DIR=/shared/data/work_dir/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# get file name
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
#run a tool to compare the features of pair files
/shared/software/tool_v2.1/tool -s1 $data/inf_tf/$mk -s1cf $data/features/$mk-cf -s1ss $data/features/$mk-ss -s2 $data/inf_tf/$nk.pdb -s2cf $data/features/$nk-cf.pdb -s2ss $data/features/$nk-ss.pdb > $data/$i.out
# move output files
mv matrix.txt $data/glosa_tf/matrix/$mk"_"$nk.txt
mv ali_struct.pdb $data/glosa_tf/aligned/$nk"_"$mk.pdb
# move back and remove tmp dir
cd $TMP_DIR/../
rm -rf $TMP_DIR
exit 0
cat run_script.sh
#!/bin/bash
#PBS -l nodes=5:ppn=72
#PBS -N job01
#PBS -j oe
#work dir
export WDIR=/shared/data/work_dir
cd $WDIR;
# use available 72 cpu in each node
export JOBS_PER_NODE=72
#gnu parallel command
parallelrun="parallel -j $JOBS_PER_NODE --slf $PBS_NODEFILE --wd $WDIR --joblog process.log --resume"
$parallelrun -a example.lst sh run_script.sh {}
#!/bin/bash
# parallel command options
i=$1
data=/shared/TF_data
# create tmp dir and work in
TMP_DIR=/shared/data/work_dir/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# get file name
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
#run a tool to compare the features of pair files
/shared/software/tool_v2.1/tool -s1 $data/inf_tf/$mk -s1cf $data/features/$mk-cf -s1ss $data/features/$mk-ss -s2 $data/inf_tf/$nk.pdb -s2cf $data/features/$nk-cf.pdb -s2ss $data/features/$nk-ss.pdb > $data/$i.out
# move output files
mv matrix.txt $data/glosa_tf/matrix/$mk"_"$nk.txt
mv ali_struct.pdb $data/glosa_tf/aligned/$nk"_"$mk.pdb
# move back and remove tmp dir
cd $TMP_DIR/../
rm -rf $TMP_DIR
exit 0
PBS提交
qsub job_script.sh
登录到其中一个节点:ssh ip-172-31-9-208
top - 09:28:03 up 15 min, 1 user, load average: 14.77, 13.44, 8.08
Tasks: 928 total, 1 running, 434 sleeping, 0 stopped, 166 zombie
Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 98.4%id, 1.4%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 193694612k total, 1811200k used, 191883412k free, 94680k buffers
Swap: 0k total, 0k used, 0k free, 707960k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15348 ec2-user 20 0 16028 2820 1820 R 0.3 0.0 0:00.10 top
15621 ec2-user 20 0 169m 7584 6684 S 0.3 0.0 0:00.01 ssh
15625 ec2-user 20 0 171m 7472 6552 S 0.3 0.0 0:00.01 ssh
15626 ec2-user 20 0 126m 3924 3492 S 0.3 0.0 0:00.01 perl
.....
顶部的所有节点都显示类似的状态,并且一次只运行~26个节点即可产生结果
我发现aws parallelcluster包含5个节点(每个节点有72个CPU),带有torque调度器和GNU Parallel 2018,2018年3月
更新 通过引入新的函数,该函数在stdin上获取输入,并并行运行脚本,效果非常好,并利用了本地机器上的所有CPU 但是,当它在远程机器上运行时,会产生
parallel: Error: test.lst is neither a file nor a block device
MCVE:
一个简单的代码,在远程机器上运行时,回显列表会产生相同的错误,但在本地机器上效果很好:
cat test.lst#包含列表
DNMT3L-5yx2B_1_N-DNMT3L-5yx2B_2_N
DNMT3L-5yx2B_1_N-DNMT3L-6brrC_3_N
DNMT3L-5yx2B_1_N-DNMT3L-6f57B_2_N
DNMT3L-5yx2B_1_N-DNMT3L-6f57C_2_N
DNMT3L-5yx2B_1_N-DUX4-6e8cA_4_N
DNMT3L-5yx2B_1_N-E2F8-4yo2A_3_P
DNMT3L-5yx2B_1_N-E2F8-4yo2A_6_N
DNMT3L-5yx2B_1_N-EBF3-3n50A_2_N
DNMT3L-5yx2B_1_N-ELK4-1k6oA_3_N
DNMT3L-5yx2B_1_N-EPAS1-1p97A_1_N
cat test_job.sh#GNU并行提交脚本
#!/bin/bash
#PBS -l nodes=1:ppn=72
#PBS -N test
#PBS -k oe
# introduce new function and Run from ~/
dowork() {
parallel sh test_work.sh {}
}
export -f dowork
parallel -a test.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
cat test_work.sh#运行/工作脚本
#!/bin/bash
i=$1
data=pwd
#create temporary folder in current dir
TMP_DIR=$data/$i
mkdir -p $TMP_DIR
cd $TMP_DIR/
# split list
mk=$(echo "$i" | cut -d- -f1-2)
nk=$(echo "$i" | cut -d- -f3-6)
# echo list and save in echo_test.out
echo $mk, $nk >> $data/echo_test.out
cd $TMP_DIR/../
rm -rf $TMP_DIR
我不确定
工具的功能。但是,如果复制占用了大部分时间,并且工具
仅读取文件,则您可以将文件符号链接到$TMP_DIR
中,而不是复制
查看集群中5台机器的top
,可以很好地指示您是否可以更快地完成此任务。如果他们都以>90%的速度使用所有内核,那么您就不能期望更快地使用。我不确定工具的功能。但是,如果复制占用了大部分时间,并且工具
仅读取文件,则您可以将文件符号链接到$TMP_DIR
中,而不是复制
查看集群中5台机器的top
,可以很好地指示您是否可以更快地完成此任务。如果他们都以>90%的速度使用所有内核,那么您就不能期望更快地获得这些内核。从您的计时:
real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
似乎该工具使用的CPU功率非常小。当GNU并行运行本地作业时,每个作业的CPU时间开销为10毫秒。您的作业使用179毫秒的时间和5毫秒的CPU时间。所以GNU并行将使用相当多的时间
远程运行作业时,开销更大。这里我们讨论的是10毫秒以上运行ssh命令。这很容易达到100毫秒左右
那么,我们如何最大限度地减少ssh命令的数量,如何将开销分散到多个核心上呢
首先,让我们创建一个函数,该函数可以接受stdin上的输入并运行脚本-每个CPU线程并行执行一个作业:
dowork() {
[...set variables here. that becomes particularly important we when run remotely...]
parallel sh run_script.sh {}
}
export -f dowork
通过运行以下命令来测试此功能是否有效:
head -n 1000 example.lst | dowork
然后让我们看看在本地运行作业。这可以像这里描述的那样进行:
这将把example.lst
拆分为每个CPU线程10个块。因此,在一台有72个CPU线程的机器上,这将产生720个块。它将启动72个doworks
,完成一个后,将获得720个块中的另一个块。我选择10而不是1的原因是,如果其中一份工作“卡住”了一段时间,那么你不太可能注意到这一点
这应确保本地计算机上的CPU 100%繁忙
如果可行,我们需要将此工作分发到远程机器:
parallel -j1 -a example.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
每个CPU线程(即5*72*10)总共应启动10个ssh
——即每个块一个。在$PBS\u NODEFILE
中列出的每台服务器上并行运行1台
不幸的是,这意味着--joblog
和--resume
将无法工作。目前还没有办法做到这一点,但如果对你有价值,请通过以下方式与我联系:parallel@gnu.org.从您的计时:
real 0m0.179s
user 0m0.005s
sys 0m0.000s sec
似乎该工具使用的CPU功率非常小。当GNU并行运行本地作业时,每个作业的CPU时间开销为10毫秒。您的作业使用179毫秒的时间和5毫秒的CPU时间。所以GNU并行将使用相当多的时间
远程运行作业时,开销更大。这里我们讨论的是10毫秒以上运行ssh命令。这很容易达到100毫秒左右
那么,我们如何最大限度地减少ssh命令的数量,如何将开销分散到多个核心上呢
首先,让我们创建一个函数,该函数可以接受stdin上的输入并运行脚本-每个CPU线程并行执行一个作业:
dowork() {
[...set variables here. that becomes particularly important we when run remotely...]
parallel sh run_script.sh {}
}
export -f dowork
通过运行以下命令来测试此功能是否有效:
head -n 1000 example.lst | dowork
然后让我们看看在本地运行作业。这可以像这里描述的那样进行:
这将把example.lst
拆分为每个CPU线程10个块。因此,在一台有72个CPU线程的机器上,这将产生720个块。它将启动72个doworks
,完成一个后,将获得720个块中的另一个块。我选择10而不是1的原因是,如果其中一份工作“卡住”了一段时间,那么你不太可能注意到这一点
这应确保本地计算机上的CPU 100%繁忙
如果可行,我们需要将此工作分发到远程机器:
parallel -j1 -a example.lst --env dowork --pipepart --slf $PBS_NODEFILE --block -10 dowork
每个CPU线程(即5*72*10)总共应启动10个ssh
——即每个块一个。在$PBS\u NODEFILE
中列出的每台服务器上并行运行1台
不幸的是,这意味着--joblog
和--resume
将无法工作。目前没有办法做到这一点