我正在尝试对 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-control
systemd 中更多有用的 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_us
cgcreate
cgset
cgroup-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_us
和cpu.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
它通过发送SIGSTOP
和SIGCONT
附加命令来暂停和恢复其操作。
据我所知,同时控制多个独立进程比较困难,比如将它们组合在一起,但也可能有解决方案......
答案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