A.2. cpu
cpu
子系统可以调度 cgroup 对 CPU 的获取量。可用以下两个调度程序来管理对 CPU 资源的获取:
- 完全公平调度程序(CFS) — 一个比例分配调度程序,可根据任务优先级 ∕ 权重或 cgroup 分得的份额,在任务群组(cgroups)间按比例分配 CPU 时间(CPU 带宽)。关于如何使用 CFS 进行资源控制,请参阅〈第 A.2.1 节 “CFS 可调度参数”〉。
- 实时调度程序(RT) — 一个任务调度程序,可对实时任务使用 CPU 的时间进行限定。关于如何进行限定,请参阅〈第 A.2.2 节 “RT 可调参数”〉。
A.2.1. CFS 可调度参数
在 CFS 中,如果系统有足够的空闲 CPU 周期,那么 cgroup 可获得比其自有份额更多的 CPU 可用量,因为该调度程序有连续工作的特性。此情况通常会在 cgroup 根据相关共享消耗 CPU 时间时出现。在需要对 cgroup 的 CPU 可用量做出硬性限制时(即任务的 CPU 时间不能超过一个特定量),可使用强制上限。
以下选项可用来配置强制上限或者 CPU 相对份额:
强制上限的可调参数
- cpu.cfs_period_us
- 此参数可以设定重新分配 cgroup 可用 CPU 资源的时间间隔,单位为微秒(µs,这里以 “
us
” 表示)。如果一个 cgroup 中的任务在每 1 秒钟内有 0.2 秒的时间可存取一个单独的 CPU,则请将cpu.rt_runtime_us
设定为2000000
,并将cpu.rt_period_us
设定为1000000
。cpu.cfs_quota_us
参数的上限为 1 秒,下限为 1000 微秒。 - cpu.cfs_quota_us
- 此参数可以设定在某一阶段(由
cpu.cfs_period_us
规定)某个 cgroup 中所有任务可运行的时间总量,单位为微秒(µs,这里以 "us
" 代表)。一旦 cgroup 中任务用完按配额分得的时间,它们就会被在此阶段的时间提醒限制流量,并在进入下阶段前禁止运行。如果 cgroup 中任务在每 1 秒内有 0.2 秒,可对单独 CPU 进行存取,请将cpu.cfs_quota_us
设定为200000
,cpu.cfs_period_us
设定为1000000
。请注意,配额和时间段参数都根据 CPU 来操作。例如,如要让一个进程完全利用两个 CPU,请将cpu.cfs_quota_us
设定为200000
,cpu.cfs_period_us
设定为100000
。如将cpu.cfs_quota_us
的值设定为-1
,这表示 cgroup 不需要遵循任何 CPU 时间限制。这也是每个 cgroup 的默认值(root cgroup 除外)。 - cpu.stat
- 此参数通过以下值报告 CPU 时间统计:
nr_periods
— 经过的周期间隔数(如cpu.cfs_period_us
中所述)。nr_throttled
— cgroup 中任务被节流的次数(即耗尽所有按配额分得的可用时间后,被禁止运行)。throttled_time
— cgroup 中任务被节流的时间总计(以纳秒为单位)。
相对比例的可调参数
- cpu.shares
- 此参数用一个整数来设定 cgroup 中任务 CPU 可用时间的相对比例。例如:
cpu.shares
设定为100
的任务,即便在两个 cgroup 中,也将获得相同的 CPU 时间;但是cpu.shares
设定为200
的任务与cpu.shares
设定为100
的任务相比,前者可使用的 CPU 时间是后者的两倍,即便它们在同一个 cgroup 中。cpu.shares
文件设定的值必须大于等于2
。请注意:在多核系统中,CPU 时间比例是在所有 CPU 核中分配的。即使在一个多核系统中,某个 cgroup 受限制而不能 100% 使用 CPU,它仍可以 100% 使用每个单独的 CPU 核。请参考以下示例:如果 cgroupA
可使用 CPU 的 25%,cgroupB
可使用 CPU 的 75%,在四核系统中启动四个消耗大量 CPU 的进程(一个在A
中,三个在B
中)后,会得到以下 CPU 分配结果:表 A.1. CPU 分配比例 PID cgroup CPU CPU 共享 100 A 0 CPU0 的 100% 101 B 1 CPU1 的 100% 102 B 2 CPU2 的 100% 103 B 3 CPU3 的 100% 使用 “相对比例” 设定 CPU 获取量来管理资源时,有两个问题需要注意:- 因为 CFS 不需要相同的 CPU 使用量,所以很难预测 cgroup 的 CPU 可用时间。当一个 cgroup 中的任务处于闲置状态且不使用任何 CPU 时间时,剩余的时间会被收集到未使用的 CPU 循环全局池中。其它 cgroup 可以从这个池中借用 CPU 循环。
- cgroup 实际可用的 CPU 时间会根据该系统中 cgroup 的数量有所不同。如果一个 cgroup 的相对份额是
1000
,另外两个 cgroup 的相对份额是500
,在所有 cgroup 中的进程都尝试使用 100% CPU 时间的条件下,第一个 cgroup 将有 50% 的 CPU 时间。但如果新添加一个相对份额为1000
的 cgroup,则第一个 cgroup 只允许使用 33% 的 CPU 时间(剩余的 cgroup 则使用 16.5%、16.5% 和 33% 的 CPU 时间)。
A.2.2. RT 可调参数
RT 调度程序与 CFS 的强制上限(详情请参阅〈第 A.2.1 节 “CFS 可调度参数”〉)类似,但只限制实时任务对 CPU 的存取。一个实时任务存取 CPU 的时间可以通过为每个 cgroup 分配运行时间和时段来设定。然后,在运行时间的特定时间段,cgroup 中的所有任务会被允许存取 CPU(例如:可允许 cgroup 中的任务每秒中运行 0.1 秒)。
- cpu.rt_period_us
- 此参数可以设定在某个时间段中 ,每隔多久,cgroup 对 CPU 资源的存取就要重新分配,单位为微秒(µs,这里以“
us
”表示),只可用于实时调度任务。如果某个 cgroup 中的任务,每秒内有 0.2 秒可存取 CPU 资源,则请将cpu.rt_runtime_us
设定为200000
,并将cpu.rt_period_us
设定为1000000
。 - cpu.rt_runtime_us
- 此参数可以指定在某个时间段中, cgroup 中的任务对 CPU 资源的最长连续访问时间,单位为微秒(µs,这里以“
us
”表示),只可用于实时调度任务。建立这个限制是为了防止一个 cgroup 中的任务独占 CPU 时间。如果 cgroup 中的任务,在每秒内有 0.2 秒可存取 CPU 资源,请将cpu.rt_runtime_us
设定为200000
,并将cpu.rt_period_us
设定为1000000
。请注意:运行时间和阶段参数会根据 CPU 操作。例如:如要允许一个实时任务完全利用两个 CPU,请将cpu.cfs_quota_us
设定为200000
并将cpu.cfs_period_us
设定为100000
。
A.2.3. 示例应用
例 A.2. 限制 CPU 存取
以下示例假设您已配置 cgroup 层级并且
cpu
子系统已挂载到您的系统中:
- 如要让一个 cgroup 使用一个 CPU 的 25%,同时另一个 cgroup 使用此 CPU 的 75%,请使用以下指令:
~]#
echo 250 > /cgroup/cpu/blue/cpu.shares
~]#echo 750 > /cgroup/cpu/red/cpu.shares
- 如要让一个 cgroup 完全使用一个 CPU,请使用以下指令:
~]#
echo 10000 > /cgroup/cpu/red/cpu.cfs_quota_us
~]#echo 10000 > /cgroup/cpu/red/cpu.cfs_period_us
- 如要让一个 cgroup 使用 CPU 的 10%,请使用以下指令:
~]#
echo 10000 > /cgroup/cpu/red/cpu.cfs_quota_us
~]#echo 100000 > /cgroup/cpu/red/cpu.cfs_period_us
- 在多核系统中,如要让一个 cgroup 完全使用两个 CPU 核,请使用以下指令:
~]#
echo 200000 > /cgroup/cpu/red/cpu.cfs_quota_us
~]#echo 100000 > /cgroup/cpu/red/cpu.cfs_period_us