本文共 6386 字,大约阅读时间需要 21 分钟。
一.cgroup介绍
Cgroups相关概念及其关系
1)blkio 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。
2)cpu 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。3)cpuacct 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。4)cpuset 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。5)devices 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。6)freezer 这个子系统挂起或者恢复 cgroup 中的任务。7)memory 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。8)net_cls 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。9)ns 名称空间子系统。二.使用
#yum install libcgroup
#cat /etc/redhat-releaseCentOS Linux release 7.2.1511 (Core)配置文件
#cat /etc/cgconfig.conf配置介绍
#cat /etc/cgrules.conf
auser:ab memory httpd用户或@组:命令 子系统 cgroup名称
@auser:ab memory httpd#systemctl restart cgconfig.service
#systemctl restart cgred.service配置是限制auser用户 执行ab时,当使用内存超过10M时,进程就会被杀。(默认配置)
内核相关的配置
这里CONFIG_MEMCG_SWAP和CONFIG_MEMCG_KMEM等于y表示内核已经编译了该模块,即支持相关功能
$cat /boot/config-uname -r
|grep CONFIG_MEMCG (我也是醉了,新版51,这引号自带背影的) CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y#CONFIG_MEMCG_SWAP_ENABLED is not setCONFIG_MEMCG_KMEM=yCONFIG_MEMCG_SWAP控制内核是否支持Swap 扩展,而CONFIG_MEMCG_SWAP_ENABLED(3.6以后的内核新加的参数)控制默认情况下是否使用Swap 扩展,由于Swap 扩展比较耗资源,所以很多发行版(比如ubuntu)默认情况下会禁用该功能(这也是上面那行被注释掉的原因),当然用户也可以根据实际情况,通过设置内核参数swapaccount=0或者1来手动禁用和启用Swap Extension。
测试
[auser@app ~]$ ab -c 10 -n 1000000
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, Licensed to The Apache Software Foundation,Benchmarking 192.168.90.177 (be patient)
Completed 100000 requestsCompleted 200000 requestsCompleted 300000 requests已杀死#top 观察auser使用ab命令时候内存使用情况,当使用超过10M大概持续2到3秒时,会发现进程被杀死。
一旦设置了内存限制,将立即生效,并且当物理内存使用量达到limit的时候,memory.failcnt的内容会加1,但这时进程不一定就会被kill掉,内核会尽量将物理内存中的数据移到swap空间上去,如果实在是没办法移动了(设置的limit过小,或者swap空间不足),默认情况下,就会kill掉cgroup里面继续申请内存的进程。
当物理内存达到上限后,系统的默认行为是kill掉cgroup中继续申请内存的进程,那么怎么控制这样的行为呢?答案是配置memory.oom_control
这个文件里面包含了一个控制是否为当前cgroup启动OOM-killer的标识。如果写0到这个文件,将启动OOM-killer,当内核无法给进程分配足够的内存时,将会直接kill掉该进程;如果写1到这个文件,表示不启动OOM-killer,当内核无法给进程分配足够的内存时,将会暂停该进程直到有空余的内存之后再继续运行;同时,memory.oom_control还包含一个只读的under_oom字段,用来表示当前是否已经进入oom状态,也即是否有进程被暂停了。#cat /cgroup/memory/httpd/memory.oom_controloom_kill_disable 0under_oom 0#echo 0 > memory.swappiness 设置swappiness为0 禁止当前cgroup使用swap
当超过限额,会被直接杀掉,不会使用swap空间。#echo 1 > /cgroup/memory/httpd/memory.oom_control 注意:不要vim编辑去写,直接echo 1进去,虽然有两行配置
oom_kill_disable等于1的时候内存达到限额的时候会暂停当临时修改扩大内存时,进程又继续工作,当又不够时,就会再次暂停工作。进程迁移
当一个进程从一个cgroup移动到另一个cgroup时,默认情况下,该进程已经占用的内存还是统计在原来的cgroup里面,不会占用新cgroup的配额,但新分配的内存会统计到新的cgroup中(包括swap out到交换空间后再swap in到物理内存中的部分)。
我们可以通过设置memory.move_charge_at_immigrate让进程所占用的内存随着进程的迁移一起迁移到新的cgroup中enable: echo 1 > memory.move_charge_at_immigrate
disable:echo 0 > memory.move_charge_at_immigrate
注意: 就算设置为1,但如果不是thread group的leader,这个task占用的内存也不能被迁移过去。换句话说,如果以线程为单位进行迁移,必须是进程的第一个线程,如果以进程为单位进行迁移,就没有这个问题。当memory.move_charge_at_immigrate为0时,就算当前cgroup中里面的进程都已经移动到其它cgropu中去了,由于进程已经占用的内存没有被统计过去,当前cgroup有可能还占用很多内存,当移除该cgroup时,占用的内存需要统计到谁头上呢?答案是依赖memory.use_hierarchy的值,如果该值为0,将会统计到root cgroup里;如果值为1,将统计到它的父cgroup里面。相关参数:
1)force_empty :
当向memory.force_empty文件写入0时(echo 0 > memory.force_empty),将会立即触发系统尽可能的回收该cgroup占用的内存。该功能主要使用场景是移除cgroup前(cgroup中没有进程),先执行该命令,可以尽可能的回收该cgropu占用的内存,这样迁移内存的占用数据到父cgroup或者root cgroup时会快些。
memory.swappiness :
该文件的值默认和全局的swappiness(/proc/sys/vm/swappiness)一样,修改该文件只对当前cgroup生效,其功能和全局的swappiness一样
有一点和全局的swappiness不同,那就是如果这个文件被设置成0,就算系统配置的有交换空间,当前cgroup也不会使用交换空间。
2)memory.use_hierarchy:
该文件内容为0时,表示不使用继承,即父子cgroup之间没有关系;当该文件内容为1时,子cgroup所占用的内存会统计到所有祖先cgroup中。
如果该文件内容为1,当一个cgroup内存吃紧时,会触发系统回收它以及它所有子孙cgroup的内存。注意: 当该cgroup下面有子cgroup或者父cgroup已经将该文件设置成了1,那么当前cgroup中的该文件就不能被修改。3)memory.soft_limit_in_bytes:
有了hard limit(memory.limit_in_bytes),为什么还要soft limit呢?hard limit是一个硬性标准,绝对不能超过这个值,而soft limit可以被超越,既然能被超越,要这个配置还有啥用?先看看它的特点
当系统内存充裕时,soft limit不起任何作用
当系统内存吃紧时,系统会尽量的将cgroup的内存限制在soft limit值之下(内核会尽量,但不100%保证)从它的特点可以看出,它的作用主要发生在系统内存吃紧时,如果没有soft limit,那么所有的cgroup一起竞争内存资源,占用内存多的cgroup不会让着内存占用少的cgroup,这样就会出现某些cgroup内存饥饿的情况。如果配置了soft limit,那么当系统内存吃紧时,系统会让超过soft limit的cgroup释放出超过soft limit的那部分内存(有可能更多),这样其它cgroup就有了更多的机会分配到内存。从上面的分析看出,这其实是系统内存不足时的一种妥协机制,给次等重要的进程设置soft limit,当系统内存吃紧时,把机会让给其它重要的进程。
注意: 当系统内存吃紧且cgroup达到soft limit时,系统为了把当前cgroup的内存使用量控制在soft limit下,在收到当前cgroup新的内存分配请求时,就会触发回收内存操作,所以一旦到达这个状态,就会频繁的触发对当前cgroup的内存回收操作,会严重影响当前cgroup的性能。
CPU、内存、IO和网络都能通过cgroup进行管控。通过资源再分配合理的优化虚拟化或者容器。
未完待续
转载于:https://blog.51cto.com/pankuo/2044862