我正在寻找一种工具,使我能够并行处理多达多个内核的bash命令列表,每个bash命令具有不同的CPU要求。
例如,如果我有一台具有3核的计算机,并且具有以下作业列表:
我希望该工具并行运行命令,但要尊重我只有3个内核的事实,因此工作量看起来像
(empty), (empty), (empty)
Job 1 (using 1 core), (empty), (empty)
Job 1 (using 1 core), Job 2 (using 2 cores)
Job 1 done, Job 2 (using 2 cores)
(empty), Job 2 (using 2 cores)
(empty), Job 2 done
Job 3 (using 3 cores)
答案 0 :(得分:5)
我的感觉是将此答案分为两个部分。 a)Shell b)Docker并提供一个序言。
nb。最初的问题与运行并行docker容器有关。然后,问题范围扩展到了并行shell脚本的主题。
在具有N个处理元素的并行计算机上运行时,理想情况下的并行编程可将N加速提高一个因子。如果您读过Amdahl’s law,则会注意到由于并行化任务所需的努力,这并不总是正确的。并行任务之间的任何相互依赖关系都将迅速造成复杂性,并可能抵消使操作并行化的努力。
如果您真的希望通过外壳创建一组并行作业,我个人的建议是使用GNU Parallel。它提供了对CPU和线程属性的极其精细的控制。
它还附带了许多详细的code example。
让我们假设一个网站存储的图像如下:
http://www.example.com/path/to/YYYYMMDD_##.jpg
其中YYYYMMDD是日期,而##是数字01-24。这将下载过去30天的图像:
getit() {
date=$(date -d "today -$1 days" +%Y%m%d)
num=$2
echo wget http://www.example.com/path/to/${date}_${num}.jpg
}
export -f getit
parallel getit ::: $(seq 30) ::: $(seq -w 24)
问题: “ 上述并行任务方法有什么问题?”
答案: 嗯,任务的并行性看起来不错,但是现在性能受到网站的IO带宽的限制...因此,许多并行任务可能会导致整体任务完成速度变慢。
在docker run命令上,您可以定义可以限制CPU资源的使用
--cpu=n
https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler
以下示例仅通过外壳for
循环构造启动了一组(假定的)非依赖docker容器。这是一种以并行方式运行一组非依赖容器的典型方法。注意:这些程序是按顺序开始的,但可以独立运行,可以在Docker IO通信背板中建立任何相互依赖关系(即它们可以通过TCP进行通信),尽管坦白地说,您正在就实际尝试的内容进行技术性讨论与并行性有关。 (当心,龙……)
1 #!/bin/bash
2
3 n="$1"
4 if [[ "$n" == "" ]]; then
5 echo "You did not specify number of parallel runs to launch. Defaulting to 10."
6 n="10"
7 fi
8
9 mkdir $PWD/openjdks
10
11 for i in $(seq 1 $n); do
12 mkdir $PWD/openjdks/$i
13 docker run -d\
14 --name=<name>$i \
15 --cap-add=SYS_ADMIN \
16 --cpu=<number of CPU required> \
17 -v $PWD/openjdks/$i:/tmp \
18 -e DISTRO=centos \
19 -r mirror \
20 -filename java-1.6.0-openjdk-1.6.0.41-1.13.13.1.el7_3.x86_64.rpm \
21 -path /tmp/java-1.6.0-openjdk-1.6.0.41-1.13.13.1.el7_3.x86_64.rpm \
22 -log /tmp/mylog.log
23 done
我希望以上内容能为您指明正确的方向。