cgroups
一. Cgroups介绍
默认cgroups配置文件在/etc/cgconfig.conf中,具体的挂载目录请参见配置文件。
重新启动:/etc/init.d/cgconfigrestart
安装包:yum install libcgroup libcgroup-tools
二. Cgroups基本概念
1. 控制组(controlgroup)。
控制组就是一组按照某种标准划分的进程。Cgroups中的资源控制都是以控制组为单位实现。一个进程可以加入到某个控制组,也从一个进程组迁移到另一个控制组。一个进程组的进程可以使用cgroups以控制组为单位分配的资源,同时受到cgroups以控制组为单位设定的限制。
2. 层级(hierarchy)。
控制组可以组织成hierarchical的形式,既一颗控制组树。控制组树上的子节点控制组是父节点控制组的孩子,继承父控制组的特定的属性。
3. 子系统(subsytem)。
一个子系统就是一个资源控制器,比如cpu子系统就是控制cpu时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。可用子系统:
· blkio--这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB等等)。
· cpu--这个子系统使用调度程序提供对CPU的cgroup任务访问。
· cpuacct--这个子系统自动生成cgroup中任务所使用的CPU报告。
· cpuset--这个子系统为cgroup中的任务分配独立CPU(在多核系统)和内存节点。
· devices--这个子系统可允许或者拒绝cgroup中的任务访问设备。
· freezer--这个子系统挂起或者恢复cgroup中的任务。
· memory--这个子系统设定cgroup中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
· net_cls--这个子系统使用等级识别符(classid)标记网络数据包,可允许Linux流量控制程序(tc)识别从具体cgroup中生成的数据包。
· ns--名称空间子系统。
三. 几个常用示例
1. CPU使用时间(使用率)限制
mkdir /cgroup/cpu/limit#创建CPU控制组limit,或cgcreate -g cpu:/limit
echo 50000> /cgroup/cpu/limit/cpu.cfs_quota_us #将cpu.cfs_quota_us设置为50000,相当于cpu.cfs_period_us值100000的50%,或cgset-r cpu.cfs_quota_us=50000 limit
echo $pid> /cgroup/cpu/limit/tasks #将需要限制CPU使用率的的进程ID写到tasks中,或cgclassify -g cpu:limit $pid
echo ‘’ >/cgroup/cpu/limit/tasks #取消限制
rmdir/cgroup/cpu/limit #删除CPU控制组limit,或cgdelete cpu:/limit
2. CPU资源绑定
mkdir/cgroup/cpuset/limit #创建CPU设置控制组limit,或cgcreate -g cpuset:/limit
echo ‘0-2,16’/cgroup/cpuset/limit/cpuset.cpus #将所绑定的CPU核ID写入到cpuset.cpus中,或cgset -r cpuset.cpus=‘0-2,16’ limit
echo $pid> /cgroup/cpuset/limit/ tasks #将需要绑定CPU核心的进程ID写入到tasks中,或cgclassify -g cpuset:limit $pid
3. 内存资源限制
mkdir/cgroup/memory/limit #创建内存控制组limit
echo 104857600> /cgroup/memory/limit/memory.limit_in_bytes #分配100M内存给这个控制组
echo $pid> /cgroup/memory/limit/tasks #将需要限制内存使用的进程ID写到tasks中,一旦进程内存超过配置的值,将发生OOM killer(Out-Of-Memory killer)
4. IO资源限制
mkdir /cgroup/blkio/limit#创建IO控制组limit
echo '252:2 1048576' > /cgroup/blkio/limit/blkio.throttle.read_bps_device #限制设置252:2读速度为1M/s,252:2为对应的主设备号和副设备号,可能通过ls -l /dev/vda2 查看,后面的数字为限制带宽
echo $pid> /cgroup/blkio/limit/tasks #将需要限制IO的进程ID写入到tasks中
四. 常用cgroups参数
通过上面,可以看到调整某个组里面的参数,并且将进程ID加入到该组中,就可以对进程进行资源控制,以下是可能用到的相关子系统的参数:
1. blkio
1.1. blkio.weight
指定cgroup默认可用访问块I/O的相对比例(加权),范围在100到1000。这个值可由具体设备的blkio.weight_device参数覆盖。例如:如果将cgroup访问块设备的默认加权设定为500,请运行:
echo 500 > blkio.weight
1.2. blkio.weight_device
指定对cgroup中可用的具体设备I/O访问的相对比例(加权),范围是100到1000。这个值可由为设备指定的blkio.weight参数覆盖。例如:如果为访问/dev/sda的cgroup分配加权500,请运行:
echo "8:0 500" > blkio.weight_device
1.3. blkio.throttle.read_bps_device
此参数用于设定设备执行“读”操作字节的上限。“读”的操作率以每秒的字节数来限定。bytes_per_second是“读”操作可被执行的上限率。例如,让/dev/sda设备运行“读”操作的最大速率是10MBps,请运行:
echo "8:0 10485760" >/cgroup/blkio/test/blkio.throttle.read_bps_device
1.4. blkio.throttle.write_bps_devicev
此参数用于设定设备执行“写”操作次数的上限。“写”的操作率用“字节/秒”来表示。bytes_per_second是“写”操作可被执行的上限率。例如,让/dev/sda设备执行“写”操作的最大比率为10MBps,请运行:
echo "8:0 10485760"> /cgroup/blkio/test/blkio.throttle.write_bps_device
1.5. blkio.throttle.read_iops_device
此参数用于设定设备执行“读”操作次数的上限。“读”的操作率以每秒的操作次数来表示。operations_per_second是“读”可被执行的上限率。例如:如要设定/dev/sda设备执行“读”的最大比率为10次/秒,请运行:
echo "8:0 10"> /cgroup/blkio/test/blkio.throttle.read_iops_device
1.6. blkio.throttle.write_iops_device
此参数用于设定设备执行“写”操作次数的上限。“写”的操作率以每秒的操作次数来表示。operations_per_second是“写”操作可被执行的上限率。例如:如要让/dev/sda设备执行“写”操作的最大比率为10次/秒,请运行:
echo "8:0 10">/cgroup/blkio/test/blkio.throttle.write_iops_device
2. cpu
2.1. cpu.shares
包含用来指定在cgroup中的任务可用的相对共享CPU时间的整数值。例如:在两个cgroup中都将cpu.shares设定为1的任务将有相同的CPU时间,但在cgroup中将cpu.shares设定为2的任务可使用的CPU时间是在cgroup中将cpu.shares设定为1的任务可使用的CPU时间的两倍。
2.2. 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微秒。
2.3. 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的默认值(rootcgroup除外)。
3. cpuset
3.1. cpuset.cpus(强制)
设定该cgroup任务可以访问的CPU。这是一个逗号分隔列表,格式为ASCII,小横线("-")代表范围。例如:
0-2,16 表示CPU0、1、2和16。
3.2. cpuset.mems(强制)
设定该cgroup中任务可以访问的内存节点。这是一个逗号分隔列表,格式为ASCII,小横线("-")代表范围。例如:
0-2,16 表示内存节点0、1、2和16。
4. memory
4.1. memory.limit_in_bytes
设定用户内存(包括文件缓存)的最大用量。如果没有指定单位,则该数值将被解读为字节。但是可以使用后缀代表更大的单位——k或者K代表千字节,m或者M代表兆字节,g或者G代表千兆字节。您不能使用memory.limit_in_bytes限制rootcgroup;您只能对层级中较低的群组应用这些值。在memory.limit_in_bytes中写入-1可以移除全部已有限制。
4.2. memory.memsw.limit_in_bytes
设定内存与swap用量之和的最大值。如果没有指定单位,则该值将被解读为字节。但是可以使用后缀代表更大的单位——k或者K代表千字节,m或者M代表兆字节,g或者G代表千兆字节。您不能使用memory.memsw.limit_in_bytes来限制rootcgroup;您只能对层级中较低的群组应用这些值。在memory.memsw.limit_in_bytes中写入-1可以删除已有限制。
4.3. memory.force_empty
当设定为0时,该cgroup中任务所用的所有页面内存都将被清空。这个接口只可在cgroup没有任务时使用。如果无法清空内存,请在可能的情况下将其移动到父cgroup中。移除cgroup前请使用memory.force_empty参数以免将废弃的页面缓存移动到它的父cgroup中。
4.4. memory.swappiness
将kernel倾向设定为换出该cgroup中任务所使用的进程内存,而不是从页高速缓冲中再生页面。这与/proc/sys/vm/swappiness为整体系统设定的倾向、计算方法相同。默认值为60。低于60会降低kernel换出进程内存的倾向;高于0会增加kernel换出进程内存的倾向。高于100时,kernel将开始换出作为该cgroup中进程地址空间一部分的页面。请注意:值0不会阻止进程内存被换出;系统内存不足时,换出仍可能发生,因为全局虚拟内存管理逻辑不读取该cgroup值。要完全锁定页面,请使用mlock()而不是cgroup。您不能更改以下群组的swappiness:
rootcgroup,它使用/proc/sys/vm/swappiness设定的swappiness;
有子群组的cgroup。
4.5. memory.oom_control
包含标签(0或者1),它可以为cgroup启用或者禁用“内存不足”(OutofMemory,OOM)终止程序。如果启用(0),尝试消耗超过其允许内存的任务会被OOM终止程序立即终止。默认情况下,所有使用memory子系统的cgroup都会启用OOM终止程序。要禁用它,请在memory.oom_control文件中写入1:
echo 1 > /cgroup/memory/lab1/memory.oom_control
禁用OOM杀手程序后,尝试使用超过其允许内存的任务会被暂停,直到有额外内存可用。memory.oom_control文件也在under_oom条目下报告当前cgroup的OOM状态。如果该cgroup缺少内存,则会暂停它里面的任务。under_oom条目报告值为1。memory.oom_control文件可以使用API通知来报告OOM情况的出现。
5. net_cls
net_cls子系统使用等级识别符(classid)标记网络数据包,这让Linux流量管控器(tc)可以识别从特定cgroup中生成的数据包。可配置流量管控器,让其为不同cgroup中的数据包设定不同的优先级。
5.1. net_cls.classid
net_cls.classid包含表示流量控制handle的单一数值。从net_cls.classid文件中读取的classid值是十进制格式,但写入该文件的值则为十六进制格式。例如:0x100001表示控制点通常写为iproute2所用的10:1格式。在net_cls.classid文件中,将以数字1048577表示。这些控制点的格式为:0xAAAABBBB,其中AAAA是十六进制主设备号,BBBB是十六进制副设备号。您可以忽略前面的零;0x10001与0x00010001一样,代表1:1。以下是在net_cls.classid文件中设定10:1控制点的示例:
echo 0x100001 > /cgroup/net_cls/red/net_cls.classid
6. net_prio
网络优先权(net_prio)子系统可以为各个cgroup中的应用程序动态配置每个网络接口的流量优先级。网络优先级是一个分配给网络流量的数值,可在系统内部和网络设备间使用。网络优先级用来区分发送、排队以net_prio.prioidx只读文件。它包含一个特有整数值,kernel使用该整数值作为这个cgroup的内部代表。net_prio.ifpriomap包含优先级图谱,这些优先级被分配给源于此群组进程的流量以及通过不同接口离开系统的流量。
echo "eth0 5"> /cgroup/net_prio/iscsi/net_prio.ifpriomap
上述指令将强制设定任何源于iscsinet_priocgroup进程的流量和eth0网络接口传出的流量的优先级为5。父cgroup也有可写入的net_prio.ifpriomap文件,可以设定系统默认优先级。