优点

优点

我正在尝试对 dd 命令的 CPU 使用率进行硬性限制。我创建了以下单元文件

[Unit]
Description=Virtual Distributed Ethernet

[Service]
ExecStart=/usr/bin/ddcommand
CPUQuota=10%

[Install]
WantedBy=multi-user.target

调用以下简单脚本

#!/bin/sh
dd if=/dev/zero of=/dev/null bs=1024k

正如我所见在本指南中,我的服务的 CPU 使用率dd不应超过 10%。但是当我运行命令时,system-cgtop使用率约为 70-75%。

我知道我做错了什么,该如何改正?

当我执行时,systemctl show dd我得到以下关于 CPU 的结果

CPUShares=18446744073709551615
StartupCPUShares=18446744073709551615
CPUQuotaPerSecUSec=100ms
LimitCPU=18446744073709551615

答案1

优点

您的解决方案是正确的,并且实际上应该是相当面向未来的;通过使用 systemd 来控制服务 cgroup 设置,例如 CPUQota。

[Unit]
Description=Virtual Distributed Ethernet

[Service]
ExecStart=/usr/bin/ddcommand
CPUQuota=10%

[Install]
WantedBy=multi-user.target

请参阅man systemd.resource-controlsystemd 中更多有用的 cgroup 设置。

缺点

不过,有两个警告,我(可能还有其他一些)偶然发现。这些警告是真的很难追踪,因为关于此问题似乎没有太多容易找到的信息,这也是这个答案的主要原因。

警告1:

CPUQuota设置仅从 systemd 213 开始可用,请参阅https://github.com/systemd/systemd/blob/master/NEWS

    * The CFS CPU quota cgroup attribute is now exposed for
      services. The new CPUQuota= switch has been added for this
      which takes a percentage value. Setting this will have the
      result that a service may never get more CPU time than the
      specified percentage, even if the machine is otherwise idle.

例如,这是一个问题Debian 杰西它只随 systemd 208 提供。作为替代方案,你可以手动使用cpu.cfs_period_us和从cpu.cfs_quota_uscgcreatecgsetcgroup-bin包,例如

sudo cgcreate -g cpu:/cpulimited
sudo cgset -r cpu.cfs_period_us=50000 cpulimited
sudo cgset -r cpu.cfs_quota_us=10000 cpulimited
sudo cgexec -g cpu:cpulimited /usr/bin/ddcommand

警告2

为了使设置cpu.cfs_period_uscpu.cfs_quota_us可用,内核需要使用 config-flag 进行编译CONFIG_CFS_BANDWIDTH。遗憾的是 3.16.x 内核Debian 杰西默认情况下不使用这个标志进行编译,请参见功能要求

这将在Debian Stretch不过。也可以使用来自jessie-backports,其应该已启用标志。


我希望这个答案能够帮助一些与我遇到同样问题的人......

附言:测试 CPUquota 是否在您的环境中正常运行的简单方法是:

$ apt-get install stress
$ systemd-run -p CPUQuota=25% --slice=stress -- stress -c <your cpu count>

并使用top或进行观察htop,负载应(均匀)分布在所有 CPU/核心上,总计达 25%。

选择

作为替代工具,我们可以使用大多数发行版中都可用的 cpu-limit,例如。

$ apt-get install cpulimit
$ cpulimit -l 10 -P /usr/bin/ddcommand

它通过发送SIGSTOPSIGCONT附加命令来暂停和恢复其操作。

据我所知,同时控制多个独立进程比较困难,比如将它们组合在一起,但也可能有解决方案......

答案2

我有一个类似的任务来限制 CPU 使用率,但用例完全不同。它是在本地机器上对回归测试套件进行压力测试,以模拟它在负载 CI 服务器上所经历的情况(导致测试行为不确定或不稳定的原因)。与 和 相反,这非常cpulimit有效stress

systemd-run -p CPUQuota="25%" --scope --uid=$USER --gid=$USER -- pytest ...

--scope让它继承当前 shell 环境,并像往常一样将命令输出到 stdout。输出中唯一的区别是以范围为单位运行 run-uN.scope作为第一行。

它需要 root 权限才能运行,我有来自 的 GUI 提示符pkttyagent。如果您需要连续多次运行该命令(例如 tweak ),每次输入密码可能会很麻烦,CPUQuota因此在上述命令前加上前缀sudo -E env PATH=$PATH可以简化任务。

以防万一,因为有报告称它在旧版本上不起作用/不受支持。

$ uname -r
4.15.0-51-generic
$ systemd --version | head -n 1
systemd 229

相关内容