本文共 6560 字,大约阅读时间需要 21 分钟。
Linux cgroup 有两个子系统支持CPU隔离。
一个是cpu子系统,另一个是cpuset子系统。.1. 完全公平调度 Completely Fair Scheduler (CFS)
原理详见 CFS用于处理以下几种进程调度策略 SCHED_OTHER SCHED_BATCH SCHED_IDLE.2. 实时调度 Real-Time scheduler (RT)
原理详见 RT用于处理以下几种进程调度策略 SCHED_FIFO SCHED_RRCFS调度针对属性为SCHED_OTHER, SCHED_BATCH, SCHED_IDLE的进程。
限制手段分为两方面, .1. 限制资源组的CPU使用硬上限, .2. 以及资源组的CPU使用权重。 CFS调度资源组内的任务在CPU空闲时超权重使用CPU资源,但是不能超过硬上限。 例子groupA : cpu.shares=250 groupB : cpu.shares=750
CFS保证了groupA的进程能使用25%的CPU资源,groupB的进程能使用75%的CPU资源。
如果CPU较空闲,groupA的进程能使用超过25%的CPU资源。 如果又加了个groupC进来,并且配置了cpu.shares = 250,那么CPU资源将在三个GROUP之间重分配。groupA : groupB : groupC = 25:75:25
注意 cpu.shares 务必 >= 2
cpu.shares只限制了使用下限,如果同时还需要设置CPU使用上限,可以通过以下两个参数来设置。
cpu.cfs_period_us = 统计CPU使用时间的周期 cpu.cfs_quota_us = 周期内允许占用的CPU时间(指单核的时间, 多核则需要在设置时累加)
如果分组中的任务在周期cpu.cfs_period_us内使用的CPU时间超过了cpu.cfs_quota_us,则进入抑制状态,并且需要等下一个周期才能继续使用CPU。
例子,周期为1秒,允许使用4秒CPU时间。(假设CPU>=4核心,表示这个组在一个使用周期(1s)内可以跑满4核资源)
cpu.cfs_period_us = 1000000cpu.cfs_quota_us = 4000000
RT调度针对属性为SCHED_FIFO, SCHED_RR的进程。
与cfs的quota和period类似,限制了CPU使用的上限。但是rt调度只限制real-time tasks的CPU使用。The RT scheduler works in a similar way to the ceiling enforcement control of the CFS (for more information, refer to Section 3.2.1, “CFS Tunable Parameters”) but limits CPU access to real-time tasks only.
cpu.rt_period_us = 统计CPU使用时间的周期
cpu.rt_runtime_us = 周期内允许任务使用单个CPU核的时间,如果系统中有多个核,则可以使用核倍数的时间 (计算方法与cfs不一样,需要注意) 例子As mentioned above, the access times are multiplied by the number of logical CPUs. For example, setting cpu.rt_runtime_us to 200000 and cpu.rt_period_us to 1000000 translates to the task being able to access a single CPU for 0.4 seconds out of every 1 second on systems with two CPUs (0.2 x 2), or 0.8 seconds on systems with four CPUs (0.2 x 4).
既然有抑制状态和CPU时间片的概念,那就有对应的统计信息
用来报告该分组内的CPU调度周期,抑制次数,抑制时长等信息。(注意它的统计不包括子分组的,另外有一个cpuacct的子系统统计信息包含了子分组的,另一篇文档会讲到)cpu.statreports CPU time statistics using the following values:已经过去多少个片段了nr_periods — number of period intervals (as specified in cpu.cfs_period_us) that have elapsed.抑制了多少次nr_throttled — number of times tasks in a cgroup have been throttled (that is, not allowed to run because they have exhausted all of the available time as specified by their quota).所有任务加起来总共抑制了多长时间throttled_time — the total time duration (in nanoseconds) for which tasks in a cgroup have been throttled.
从统计信息的抑制时间和抑制次数,可以判断是否需要给分组增加CPU的上限。
.1.
限制组cgroupA的任务最多可以使用8核资源 限制组cgroupB的任务最多可以使用16核资源加载CPU子系统,创建子资源分区
mkdir -p /cgroup/cpumount -t cgroup -o cpu cpu /cgroup/cpucd /cgroup/cpumkdir cgroupAmkdir cgroupB
配置资源配比(以100为基数,核数乘以100即得到cpu.shares)
cd cgroupAecho 800 > cpu.sharesecho 1000000 > cpu.cfs_period_usecho 8000000 > cpu.cfs_quota_uscd ../cgroupBecho 1600 > cpu.sharesecho 1000000 > cpu.cfs_period_usecho 16000000 > cpu.cfs_quota_us
运行任务
cgexec -g cpu:cgroupA pg_ctl start -D /home/digoal/pgdata1921cgexec -g cpu:cgroupB pg_ctl start -D /home/digoal/pgdata1922
.1. 限下限
cpu.shares.2. 限上限 cpu.cfs_period_us cpu.cfs_quota_us .3. 限实时任务上限 cpu.rt_period_us cpu.rt_runtime_uscpuacct 子系统是用来统计CPU使用情况的子系统,功能定位不是隔离资源,而是统计资源的使用情况。
cpuacct子系统的统计数据包含子分区的。 例如/cgroup/cpuacct /cgroup/cpuacct/cg1 /cgroup/cpuacct/cg1/cg2
/cgroup/cpuacct/cg1 包含了 /cgroup/cpuacct/cg1/cg2中所有tasks 的统计数据
/cgroup/cpuacct 包含了 /cgroup/cpuacct/cg1中所有tasks以及/cgroup/cpuacct/cg1/cg2中所有tasks 的统计数据 用法和其他子系统一样。统计项
cpuacct.usage 所有cpu核的累加使用时间(nanoseconds) cpuacct.usage_percpu 针对多核,输出的是每个CPU的使用时间(nanoseconds) cpuacct.stat 输出系统(system/kernel mode)耗时和用户(user mode)耗时 , 单位为USER_HZ。
重置统计信息
reset cpuacct.usage and cpuacct.usage_percpuecho 0 > /cgroup/cpuacct/cpuacct.usage
内核时钟的频率是由CONFIG_HZ决定的,以前默认是100HZ,现在内核默认是250HZ。
1个jiffy是1个时钟滴答,时间间隔是有CONFIG_HZ决定的,频率是250HZ,也就是周期为4ms。每4ms,增加一个时钟滴答,也即jiffies++。 获取CONFIG_HZ的值(我的系统是1000)# grep ^CONFIG_HZ /boot/config-`uname -r`CONFIG_HZ_1000=yCONFIG_HZ=1000
还有一个值是USER_HZ,times系统调用是统计进程时间消耗的,并且times系统调用的时间单位是由USER_HZ决定的,所以,times系统调用统计的时间是以10ms为单位的。
说100HZ空口无凭,如何获取USER_HZ。 获取 USER_HZ的值# getconf CLK_TCK100
times系统调用来统计进程信息我不建议使用了,精度太低了。
提出这个USER_HZ,只是希望不要困惑,为什么CONFIG_HZ是250,而sysconf(_SC_CLK_TCK)却是100. 也即是说,cpuacct统计的cpuacct.stat 并不精确。 参考比如我给某个组分配了4个CPU,那么如何统计它的CPU利用率呢?
需要创建一个cpuacct组,同时将这些进程划入cpuacct. 计算方法 : cpuacct.usage / (1000 cpu.stat.nr_periods cpu.cfs_quota_us)如果你的环境是这样的启动了两个PG实例,并且在一个cpu组限制,如何统计每个PG实例的CPU利用率呢?
mkdir -p /cgroup/cpumkdir -p /cgroup/cpuacctmount -t cgroup -o cpu cpu /cgroup/cpumount -t cgroup -o cpuacct cpuacct /cgroup/cpuacctcgcreate -g cpu:cg1cgcreate -g cpuacct:cg1cgcreate -g cpuacct:cg2echo "100" > /cgroup/cpu/cg1/cpu.sharesecho "1000000" > /cgroup/cpu/cg1/cpu.cfs_period_usecho "1000000" > /cgroup/cpu/cg1/cpu.cfs_quota_usecho "1000000" > /cgroup/cpu/cg1/cpu.rt_period_usecho "1000" > /cgroup/cpu/cg1/cpu.rt_runtime_us. /home/digoal/env_pg.shcgexec -g cpu:cg1 -g cpuacct:cg1 su - digoal -c ". ~/env_pg.sh ; pg_ctl start -D /data01/pgdata1"cgexec -g cpu:cg1 -g cpuacct:cg2 su - digoal -c ". ~/env_pg.sh ; pg_ctl start -D /data01/pgdata2"
计算方法 :
实例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的调度策略都要设置,因为你并不知道程序会如何设置它的调度策略。)yum install -y libcgroupmkdir -p /cgroup/cpumkdir -p /cgroup/cpuacctmount -t cgroup -o cpu cpu /cgroup/cpumount -t cgroup -o cpuacct cpuacct /cgroup/cpuacctcgcreate -g cpu:cg1cgcreate -g cpuacct:cg1echo "100" > /cgroup/cpu/cg1/cpu.sharesecho "1000000" > /cgroup/cpu/cg1/cpu.cfs_period_usecho "1000000" > /cgroup/cpu/cg1/cpu.cfs_quota_usecho "1000000" > /cgroup/cpu/cg1/cpu.rt_period_usecho "1000" > /cgroup/cpu/cg1/cpu.rt_runtime_us# Since a non-blocking infinite loop in a process scheduled under SCHED_FIFO # or SCHED_RR will block all processes with lower priority forever, # a software developer should always keep available on the console a shell # scheduled under a higher static priority than the tested application. # This will allow an emergency kill of tested real-time applications that do not # block or terminate as expected. . /home/digoal/env_pg.shcgexec -g cpu:cg1 -g cpuacct:cg1 su - digoal -c ". ~/env_pg.sh ; pg_ctl start"
清除cgroup子分区和子系统
. /home/digoal/env_pg.shsu - digoal -c ". ~/env_pg.sh ; pg_ctl stop -m fast -w -t 600"cgdelete cpu:cg1cgdelete cpuacct:cg1cgclear cpucgclear cpuacctumount /cgroup/cpuumount /cgroup/cpuacct
如何查看程序设置的调度策略
/proc/pid/sched | grep policy
设置调度策略的接口
sched_setschedulerman 2 sched_setscheduler
转载地址:http://orfsa.baihongyu.com/