并行:超过内存限制阈值时暂停(换出)长时间运行的进度

并行:超过内存限制阈值时暂停(换出)长时间运行的进度

假设我有 10 GB RAM 和无限交换空间。

我想并行运行 10 个作业(gnu 并行是一种选择,但不一定是唯一的)。这些工作逐渐需要越来越多的内存,但它们开始时很小。这些是占用 CPU 资源的作业,每个作业都在 1 个内核上运行。

例如,假设每个作业运行 10 小时,开始时需要 500MB 内存,完成后需要 2GB,内存线性增加。因此,如果我们假设它们线性增加,那么在 6 小时 40 分钟时,这些作业将超过 10GB 的可用内存。

我如何管理这些作业,以便它们始终在 RAM 中运行,暂停处决其中一些人而让其他人逃跑?

GNU 并行可以做到这一点吗?

答案1

自六月以来情况发生了变化。

Git 版本 e81a0eba 现在有--memsuspend

--memsuspend size (alpha testing)

Suspend jobs when there is less than 2 * size memory free. The size can be
postfixed with K, M, G, T, P, k, m, g, t, or p which would multiply the size
with 1024, 1048576, 1073741824, 1099511627776, 1125899906842624, 1000,
1000000, 1000000000, 1000000000000, or 1000000000000000, respectively.

If the available memory falls below 2 * size, GNU parallel will suspend some
of the running jobs. If the available memory falls below size, only one job
will be running.

If a single job takes up at most size RAM, all jobs will complete without
running out of memory. If you have swap available, you can usually lower
size to around half the size of a single jobs - with the slight risk of
swapping a little.

Jobs will be resumed when more RAM is available - typically when the oldest
job completes.

答案2

不,但你可以杀死它们并重试它们:

memeater() {
  # Simple example that eats 10 MB/second up to 1 GB
  perl -e '$|=1;
    print "start @ARGV\n";
    for(1..100) {
      `sleep 0.1`;
      push @a, "a"x10_000_000;
    }
    print "end @ARGV\n";' $@;
}
export -f memeater

# Only start a job if there is 20 GB RAM free.
# Kill the youngest job when there is 10 GB RAM free.
parallel --retries 100 -j0 --delay 0.1 --memfree 20G memeater ::: {1..100}

如果添加,--lb您可以看到一些作业已启动,但在结束之前被终止。然后它们稍后将再次启动 - 最多 100 次,之后 GNU Parallel 放弃该工作。

相关内容