如何限制每个用户可以使用的CPU内核数量?


18

我们有一台计算机,其CPU具有32个内核,并且将由几个不同的用户用于运行程序。是否有任何方法可以限制每个用户在任何时候都可以使用的内核数,以使一个用户不会垄断所有的CPU能力?


5
没有答案,只有一个主意。您可能要考虑设置几个虚拟机。每个服务器只能具有有限数量的CPU。每个用户只能在一个虚拟机上,并且该VM上的用户的CPU使用率将受到限制。某些虚拟化软件可能具有支持此功能的工具。
ghellquist,

1
@ghellquist,您应该做出答案
slebetman

@ghellquist:如果您只想让不同的用户只看到某些CPU,那么您可能想要一些重量轻的东西,例如Linux容器。(例如,当他们启动一个OpenMP或其他程序时,该程序启动的线程数与内核数一样多,它将为您允许每个用户实际使用的内核数启动一个适当的数字)。即使使用VT-X或AMD-V之类的硬件支持,完全虚拟化也具有性能成本,即使避免了VM退出,也要从额外级别的页表中获取代码,而这种代码会使接触大量内存的任何TLB遗漏。
彼得·科德斯

对不起,但是甚至需要吗?作为多用户系统,Linux默认情况下已经实现了抢先式多任务处理,因此不应该出现单个(非恶意)用户只为整个系统生猪的情况。
立方

Answers:


16

尽管这是可能的,但它很复杂,几乎可以肯定是一个坏主意。如果当前只有一个用户在使用该计算机,则将它们限制为N个核将浪费资源。更好的方法是使用以下命令运行所有内容nice

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).

这是设置流程优先级的好工具。因此,如果只有一个用户在运行某项任务,他们将获得所需的CPU时间,但是如果其他人启动了自己的(也很出色)的工作,那么他们会很不错并且彼此共享。这样,如果您的用户都使用以下命令启动命令nice 10 command,则没有人会浪费资源(也没有人会屈服于服务器)。

注意,高nice值意味着低优先级。这是衡量多么我们应该我们越好,我们分享的越多。

另请注意,这将无助于管理内存分配,只会影响CPU调度。因此,如果多个用户启动了多个内存密集型进程,您仍然会遇到问题。如果这是一个问题,则应研究适当的排队系统,例如扭矩


感谢您的回答。有一些“工作量管理器”,例如SLURM,但它们用于具有多个节点的计算机。我认为人们没有为单节点计算机开发类似的应用程序是有道理的,因为需求不那么多。
Reza

@Reza try nice,根据您的描述,这几乎就是您所需要的。
terdon

3
@Reza:那是因为操作系统已经做到了。它会根据需要自动将可用的CPU分时共享给线程/进程。
BlueRaja-Danny Pflughoeft

13

TL; DR:从简要的研究看来,可以将命令限制为特定数量的内核,但是在所有情况下,您都必须使用实际上强制执行限制的命令。

小组

Linux具有cgroups经常用于限制进程可用资源的目的。通过一项非常简短的研究,您可以在Arch Wiki中找到一个示例,其中包含Matlab(科学软件)配置,该示例设置为/etc/cgconfig.conf

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}

为了使这种配置生效,您必须通过cgexec命令运行该过程,例如,从同一Wiki页面运行:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

任务集

有关 Ask Ubuntu和如何在Linux中将进程限制为一个CPU内核相关问题Unix&Linux站点上的[duplicate]显示了一个taskset用于限制进程CPU 的示例。第一个问题是通过解析特定用户的所有流程来实现的

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001

在另一个问题中,过程是通过taskset自身启动的:

$ taskset -c 0 mycommand --option  # start a command with the given affinity

结论

虽然当然可以限制流程,但要实现特定用户的目标似乎并非那么简单。链接的Ask Ubuntu帖子中的示例将要求对属于每个用户并taskset在每个新用户上使用的进程进行一致的扫描。一种更合理的方法是通过cgexectaskset; 有选择地运行CPU密集型应用程序。将所有进程限制为特定数量的CPUS也没有意义,特别是对于那些实际上使用并行性和并发性来更快地运行其任务的处理器-将它们限制为特定数量的CPU可能会减慢处理速度。另外,正如terdon的回答所述,这是浪费资源

通过taskset或运行cgexec与用户的通信来运行选择的应用程序,以使用户知道他们可以运行哪些应用程序,或者创建包装器脚本来通过tasksel或启动选择的应用程序cgexec

此外,考虑设置用户或组可以生成的进程数,而不是设置CPU数限制。这可以通过/etc/security/limits.conffile实现。

也可以看看


1
很好,有cgrulesengdcgrules.conf可以根据用户/组自动将进程移至适当的cgroup,而不是依靠用户使用cgexec运行其进程。但似乎在ubuntu中进行设置并非易事
汉斯·雅各布

@ Hans-Jakob看起来确实有些费解,而且需要在GRUB中添加内核标志。可能对于企业级别的计算机而言,您确实有很多用户并且不希望他们使系统崩溃,这可能是值得的,但是对于台式机而言,工作量太多。感谢您的链接。
Sergiy Kolodyazhnyy

2
sched_setaffinity(2)说亲和力掩码被保留跨越execve(2)一个孩子继承它fork(2)。因此,如果您为用户的外壳(或X会话的图形外壳)任务集,则默认情况下,他们从该外壳启动的所有内容都将使用相同的相似性掩码。
彼得·科德斯

1
一种可能的缺点是,程序在确定要启动的线程数时会检查计算机有多少个CPU。对于实际调度的内核数,它们将具有太多线程。您是否发现cgroups对此可以采取任何措施?
彼得·科德斯

@PeterCordes产生贝壳的想法听起来很有趣。我需要调查一下。谢谢 !至于第二点评论,不,我目前对cgroups的研究还不够。
Sergiy Kolodyazhnyy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.