linux cgroup 有两个子系统支持cpu隔离。
一个是cpu子系统,另一个是cpuset子系统。
.1. 完全公平调度 completely fair scheduler (cfs)
原理详见
<a href="https://www.kernel.org/doc/documentation/scheduler/sched-design-cfs.txt">https://www.kernel.org/doc/documentation/scheduler/sched-design-cfs.txt</a>
cfs用于处理以下几种进程调度策略
sched_other
sched_batch
sched_idle
.2. 实时调度 real-time scheduler (rt)
<a href="https://www.kernel.org/doc/documentation/scheduler/sched-rt-group.txt">https://www.kernel.org/doc/documentation/scheduler/sched-rt-group.txt</a>
rt用于处理以下几种进程调度策略
sched_fifo
sched_rr
cfs调度针对属性为sched_other, sched_batch, sched_idle的进程。
限制手段分为两方面,
.1. 限制资源组的cpu使用硬上限,
.2. 以及资源组的cpu使用权重。
cfs调度资源组内的任务在cpu空闲时超权重使用cpu资源,但是不能超过硬上限。
例子
cfs保证了groupa的进程能使用25%的cpu资源,groupb的进程能使用75%的cpu资源。
如果cpu较空闲,groupa的进程能使用超过25%的cpu资源。
如果又加了个groupc进来,并且配置了cpu.shares = 250,那么cpu资源将在三个group之间重分配。
注意 cpu.shares 务必 >= 2
cpu.shares只限制了使用下限,如果同时还需要设置cpu使用上限,可以通过以下两个参数来设置。
如果分组中的任务在周期cpu.cfs_period_us内使用的cpu时间超过了cpu.cfs_quota_us,则进入抑制状态,并且需要等下一个周期才能继续使用cpu。
例子,周期为1秒,允许使用4秒cpu时间。(假设cpu>=4核心,表示这个组在一个使用周期(1s)内可以跑满4核资源)
rt调度针对属性为sched_fifo, sched_rr的进程。
与cfs的quota和period类似,限制了cpu使用的上限。但是rt调度只限制real-time tasks的cpu使用。
cpu.rt_period_us = 统计cpu使用时间的周期
cpu.rt_runtime_us = 周期内允许任务使用单个cpu核的时间,如果系统中有多个核,则可以使用核倍数的时间 (计算方法与cfs不一样,需要注意)
既然有抑制状态和cpu时间片的概念,那就有对应的统计信息
用来报告该分组内的cpu调度周期,抑制次数,抑制时长等信息。(注意它的统计不包括子分组的,另外有一个cpuacct的子系统统计信息包含了子分组的,另一篇文档会讲到)
从统计信息的抑制时间和抑制次数,可以判断是否需要给分组增加cpu的上限。
.1.
限制组cgroupa的任务最多可以使用8核资源
限制组cgroupb的任务最多可以使用16核资源
加载cpu子系统,创建子资源分区
配置资源配比(以100为基数,核数乘以100即得到cpu.shares)
运行任务
.1. 限下限
cpu.shares
.2. 限上限
cpu.cfs_period_us
cpu.cfs_quota_us
.3. 限实时任务上限
cpu.rt_period_us
cpu.rt_runtime_us
cpuacct 子系统是用来统计cpu使用情况的子系统,功能定位不是隔离资源,而是统计资源的使用情况。
cpuacct子系统的统计数据包含子分区的。
例如
/cgroup/cpuacct/cg1 包含了 /cgroup/cpuacct/cg1/cg2中所有tasks 的统计数据
/cgroup/cpuacct 包含了 /cgroup/cpuacct/cg1中所有tasks以及/cgroup/cpuacct/cg1/cg2中所有tasks 的统计数据
用法和其他子系统一样。
统计项
重置统计信息
内核时钟的频率是由config_hz决定的,以前默认是100hz,现在内核默认是250hz。
1个jiffy是1个时钟滴答,时间间隔是有config_hz决定的,频率是250hz,也就是周期为4ms。每4ms,增加一个时钟滴答,也即jiffies++。
获取config_hz的值(我的系统是1000)
还有一个值是user_hz,times系统调用是统计进程时间消耗的,并且times系统调用的时间单位是由user_hz决定的,所以,times系统调用统计的时间是以10ms为单位的。
说100hz空口无凭,如何获取user_hz。
获取 user_hz的值
times系统调用来统计进程信息我不建议使用了,精度太低了。
提出这个user_hz,只是希望不要困惑,为什么config_hz是250,而sysconf(_sc_clk_tck)却是100.
也即是说,cpuacct统计的cpuacct.stat 并不精确。
参考
<a href="http://blog.chinaunix.net/uid-24774106-id-3877992.html">http://blog.chinaunix.net/uid-24774106-id-3877992.html</a>
比如我给某个组分配了4个cpu,那么如何统计它的cpu利用率呢?
需要创建一个cpuacct组,同时将这些进程划入cpuacct.
计算方法 :
cpuacct.usage / (1000 cpu.stat.nr_periods cpu.cfs_quota_us)
如果你的环境是这样的启动了两个pg实例,并且在一个cpu组限制,如何统计每个pg实例的cpu利用率呢?
实例1 cpu利用率
rg1: cpuacct.usage / (1000 cpu.stat.nr_periods cpu.cfs_quota_us)
实例2 cpu利用率
rg2: cpuacct.usage / (1000 cpu.stat.nr_periods cpu.cfs_quota_us)
如果要限制cpu,同时还需要统计进程的cpu使用资源情况。可以将task同时放到cpu和cpuacct子系统。
(注意rt和cfs的调度策略都要设置,因为你并不知道程序会如何设置它的调度策略。)
清除cgroup子分区和子系统
如何查看程序设置的调度策略
设置调度策略的接口