今天遇到cgroup资源限制,内存限制不起作用。一开始,进程的cgroup最大内存限制设置为10M,但运行几分钟后,内存明显增加,甚至达到20M以上。场景还原在memory.limit_in_bytes中设置如下:10485760代表字节数,等于1024*1024*10=10M。运行一段时间后,查看实际使用的内存。memory.usage_in_bytes文件中的值如下:可以看到,真的很好处理。好像是内存限制成功了,没有问题。但是用top命令查看的时候,发现内存消耗已经达到了23M左右,明显不正常。使用前端监控界面查看,得到相同的结果:可以看出,虽然设置了cgroup,看似有效,但实际上并没有被限制。排查问题因为这个程序的资源限制是使用agent代理程序完成的,不是人为的,所以一开始怀疑是进程没有加入cgroup资源限制策略,后来检查排除了这种可能.第一步找到进程PID及其对应的线程ID,如下图:然后查看tasks中添加的进程号,如下:可以看到该进程的所有进程号和线程号都已经添加到cgroup中.因此,它不是由此引起的。然后我想知道是否使用了交换内存。可以看出8G交换内存中的24M已经被使用了,看起来有点像。为了验证这个猜想,我先停止进程,然后查看swap内存使用情况:可以看到停止flow进程后,swap内存从24M降到20K,好像是这个东西搞的鬼.于是查看了memory.swappiness,值竟然达到了30,看来这个问题并没有消失。解决问题一旦你知道问题是什么,解决它就会更容易。第一步是将memory.swappiness设置为0。$echo0>memory.swappiness并重新启动进程。这次成功了。内存刚到10M的时候直接kill了。但实际上,我并不希望这个进程被如此简单粗暴地杀死。考虑到memory.oom_control可以设置内存达到限制后的处理措施,oom_kill_disable为0表示内存超过限制时kill进程,oom_kill_disable为1代表继续等待,当有内存释放时,继续申请内存。总而言之,进程不会被杀死。所以,设置oom_kill_disable为1后重启程序,问题解决。总结cgroup是linux系统内核提供的一种资源限制策略,使用起来非常方便。著名的Docker容器就是基于这种技术。日常工作中缺乏对这项技术的研究和积累。只知道简单的使用,并没有深入研究过每个参数代表什么,它的内在原理是什么,所以遇到这种问题费时费力。例如,memory.swappiness中的值是什么意思?为什么cgroup设置为0后还能工作?原来的30代表什么?查了资料得知,memory.swappiness中的值并不是一个精确的值,而是代表进程使用的swap空间的一个权重。取值范围为0到100。100表示activeuseofswap,0表示优先使用Memory。参考资料:dockercgroup技术记忆(第一篇)
