cgroups(ControlGroups)是内核提供的一种机制,为了不同用户层面的资源管理,提供一个统一化的接口。从单个进程的资源控制到操作系统层面的虚拟化。
task(任务):cgroups的术语中,task就表示系统的一个进程。
cgroup(控制组):cgroups中的资源控制都以cgroup为单位实现。cgroup表示按某种资源控制标准划分而成的任务组,包含一个或多个子系统。一个任务可以加入某个cgroup,也可以从某个cgroup迁移到另外一个cgroup。
subsystem(子系统):cgroups中的subsystem就是一个资源调度控制器(ResourceController)。比如CPU子系统可以控制CPU时间分配,内存子系统可以限制cgroup内存使用量。
hierarchy(层级树):hierarchy由一系列cgroup以一个树状结构排列而成,每个hierarchy通过绑定对应的subsystem进行资源调度。hierarchy中的cgroup节点可以包含零或多个子节点,子节点继承父节点的属性。整个系统可以有多个hierarchy。
cgroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(OutofMemory)。
通过分配的CPU时间片数量及硬盘IO带宽大小,实际上就相当于控制了进程运行的优先级。
cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等等,这个功能非常适用于计费。
cgroups可以对进程组执行挂起、恢复等操作。
如图所示,cgroup的子系统主要包括blkio、cpu、cpuacct、cpuset、devices、freezer、memory、perfevent等系统,基本经常使用的就是blkio、cpu、memory、cpuset。简单介绍一下这些常用的子系统的各个字段。
blkio.weight:填写100-1000的一个整数值,作为相对权重比率,作为通用的设备分配比。
blkio.weight_device:针对特定设备的权重比。
blkio.throttle.read_bps_device:按每秒读取块设备的数据量设定上限,格式device_types:
node_numbersbytes_per_second。
blkio.throttle.write_bps_device:按每秒写入块设备的数据量设定上限,格式device_types:
node_numbersbytes_per_second。
blkio.throttle.read_iops_device:按每秒读操作次数设定上限,格式device_types:
node_numbersoperations_per_second。
blkio.throttle.write_iops_device:按每秒写操作次数设定上限,格式device_types:
node_numbersoperations_per_second。
blkio.throttle.io_serviced:针对特定操作按每秒操作次数设定上限,格式
device_types:node_numbersoperation_per_second。
blkio.throttle.io_service_bytes:针对特定操作按每秒数据量设定上限,格式device_types:node_numbersoperationbytes_per_second。
cpu.cfs_period_us:设定周期时间,必须与cfs_quota_us配合使用。
cpu.cfs_quota_us :设定周期内最多可使用的时间。这里的配置指task对单个cpu的使用上限,若cfs_quota_us是cfs_period_us的两倍,就表示在两个核上完全使用。数值范围为1000-1000,000(微秒)。
cpu.stat:统计信息,包含nr_periods(表示经历了几个cfs_period_us周期)、nr_throttled(表示task被限制的次数)及throttled_time(表示task被限制的总时长)。
cpu.shares:设定一个整数(必须大于等于2)表示相对权重,最后除以权重总和算出相对比例,按比例分配CPU时间。(如cgroupA设置100,cgroupB设置300,那么cgroupA中的task运行25%的CPU时间。对于一个4核CPU的系统来说,cgroupA中的task可以100%占有某一个CPU,这个比例是相对整体的一个值)。
实时调度策略与公平调度策略中的按周期分配时间的方法类似,也是在周期内分配一个固定的运行时间。
cpu.rt_period_us :设定周期时间。
cpu.rt_runtime_us:设定周期中的运行时间。
cpuacct.usage:统计cgroup中所有task的cpu使用时长。
cpuacct.stat:统计cgroup中所有task的用户态和内核态分别使用cpu的时长。
cpuacct.usage_percpu:统计cgroup中所有task使用每个cpu的时长。
cpuset.cpus:在这个文件中填写cgroup可使用的CPU编号,如0-2,16代表0、1、2和16这4个CPU。
cpuset.mems:与CPU类似,表示cgroup可使用的memorynode,格式同上。
memory.limit_bytes:强制限制最大内存使用量,单位有k、m、g三种,填-1则代表无限制。
memory.soft_limit_bytes:软限制,只有比强制限制设置的值小时才有意义。填写格式同上。当整体内存紧张的情况下,task获取的内存就被限制在软限制额度之内,以保证不会有太多进程因内存挨饿。可以看到,加入了内存的资源限制并不代表没有资源竞争。
memory.memsw.limit_bytes:设定最大内存与swap区内存之和的用量限制。填写格式同上。
memory.oom_control:该参数填0或1, 0表示开启,当cgroup中的进程使用资源超过界限时立即杀死进程,1表示不启用。默认情况下,包含memory子系统的cgroup都启用。当oom_control不启用时,实际使用内存超过界限时进程会被暂停直到有空闲的内存资源。
memory.usage_bytes:报告该cgroup中进程使用的当前总内存用量(以字节为单位)。
memory.max_usage_bytes:报告该cgroup中进程使用的最大内存用量。
memory.failcnt:报告内存达到在memory.limit_in_bytes设定的限制值的次数。
memory.stat:包含大量的内存统计数据。
yum -y install libcgroup-tools.x86_64
sudo apt-get install cgroup-bin
cgclassify -- cgclassify命令是用来将运行的任务移动到一个或者多个cgroup。
cgclear -- cgclear 命令是用来删除层级中的所有cgroup。
cgconfig.conf -- 在cgconfig.conf文件中定义cgroup。
cgconfigparser -- cgconfigparser命令解析cgconfig.conf文件和并挂载层级。
cgcreate -- cgcreate在层级中创建新cgroup。
cgdelete -- cgdelete命令删除指定的cgroup。
cgexec -- cgexec命令在指定的cgroup中运行任务。
cgget -- cgget命令显示cgroup参数。
cgred.conf -- cgred.conf是cgred服务的配置文件。
cgrules.conf -- cgrules.conf 包含用来决定何时任务术语某些 cgroup的规则。
cgrulesengd -- cgrulesengd 在 cgroup 中发布任务。
cgset -- cgset 命令为 cgroup 设定参数。
lscgroup -- lscgroup 命令列出层级中的 cgroup。
lssubsys -- lssubsy
当然也可以用mkdir和rmdir代替cgcreate和cgdelete,也可以用脚本echo+重定向的方式代替cgset等,命令不唯一。