Linux资源控制(LXC控制CPU,内存)
2016-03-23 17:37
645 查看
主要介绍Linux下,如果对进程的CPU和内存资源的使用情况进行控制的方法。
每个进程能够占用CPU多长时间,什么时候能够占用CPU是和系统的调度密切相关的.
Linux系统中有多种调度策略,各种调度策略有其适用的场景,也很难说哪种调度策略是最优的.
Linux的调度策略可以参见代码:include/linux/sched.h
Linux系统也提供了修改调度策略的命令和系统调用接口.
调用接口请查询相关文档,这里主要介绍一下修改调度策略的命令-chrt.
补充:
chrt也可以直接指定一条命令,并设置这条命令的优先级的调度策略,具体查看chrt--help
查看一个进程的调度策略,除了使用chrt命令之外,还可以cat/proc/<PID>/sched
所谓的实时进程,也就是那些对响应时间要求比较高的进程.
这类进程需要在限定的时间内处理用户的请求,因此,在限定的这段时间内,需要占用所有CPU资源,并且不能被其它进程打断.
在这种情况下,如果实时进程中出现了类似死循环之类的情况,就会导致整个系统无响应.
因为实时进程的CPU优先级高,并且未处理完之前是不会释放CPU资源的.
所以,内核中需要有一种方式来限制实时进程的CPU资源占用.
1.获取当前系统的设置
这个设置说明实时进程在运行时并不是完全占用CPU的,每1秒中有0.05秒的时间可以给其它进程运行.
这样既不会对实时进程的响应时间造成太大的影响,也避免了实时进程卡住时导致整个系统无响应.
2.设置实时进程占用CPU时间
上面的默认设置中,实时进程占用95%的CPU时间.如果觉得占用的太多或太少,都是可以调整的.比如:
整体设置是针对整个系统的,我们也可以通过cgroup来对一组进程的CPU资源进行控制.
如果想在cgroup中对sched_rt_period_us和sched_rt_runtime_us进行控制,需要内核编译选项CONFIG_RT_GROUP_SCHED=y
查看当前系统的内核编译选项方法如下:(debian7.6系统)
查看CONFIG_RT_GROUP_SCHED是否启用
debian7.6默认没有启动这个选项,所以挂载cgroup之后,没有设置sched_rt_period_us和sched_rt_runtime_us的文件
果然,只有cpu.share,没有cpu.sched_rt_period_us和cpu.sched_rt_runtime_us
没办法,重新编译内核,编译内核的具体方法参见:编译Linux内核
为了节约时间,我们用makelocalmodconfig来创建.config文件,然后修改其中的CONFIG_RT_GROUP_SCHED=y
下载源码等等参见:编译Linux内核,主要步骤如下:
启动到新内核,再次查看内核选项CONFIG_RT_GROUP_SCHED是否启用
再次挂载cgroup文件系统,发现多了2个配置文件,cpu.rt_period_us和cpu.rt_runtime_us
通过配置cpu.rt_period_us和cpu.rt_runtime_us就可以对cgroup中的进程组中的实时进程进行CPU使用时间的控制.
上面主要介绍资源的一些理论基础,下面通过一些实例演示如果通过cgroup来控制进程所使用的CPU和内存资源.
Linux对CPU和内存的控制有对应的cgroup子系统cpuset和memory
对各个*子cgroup*的CPU占用率进行控制主要依靠每个*子cgroup*的cpu.shares文件
直接用实验过程来说话,其中加入了一些注释.
实例1-默认情况,A和B各占CPU总资源的1/2
挂载cgroup文件系统(注意加上-ocpu的选项)
在cgroup中创建2个子cgroupA和B
默认情况下,cgroupA和cgroupB中的cpu.shares中的数值都是1024
在A和B中用stress工具使其CPU占用率达到100%
top命令查看A和B中进程分别占用的CPU(应该都是50%)
可以看出,A和B组中的2个stress进程的CPU使用率相加都是100%,
由于我测试的电脑是双核,top所看到的CPU最大使用率是200%,所以和预期一致,A和B组各占CPU总资源的1/2
实例2-Agroup占用整体CPU资源的2/3,Bgroup占用整体CPU资源的1/3
环境同实例1,不再重新挂载cgroup文件系统,也不在重建A和B
Agroup的cpu.shares文件不变,值为1024
Bgroup的cpu.shares文件中的值改为512,这样,相当于B占用CPU总资源的1/3(因为512/(512+1024)=1/3)
同实例1,通过2个shell窗口,分别是A和B的CPU使用率达到100%,然后通过top查看CPU使用情况
很明显,A组中的2个进程占用了CPU总量的2/3左右,B组中的2个进程占用了CPU总量的1/3左右.
实例3-物理CPU的控制
上面的实例中,虽然能够控制每个组的CPU的总体占用率,但是不能控制某个组的进程固定在某个物理CPU上运行.
要想将cgroup绑定到某个固定的CPU上,需要使用cpuset子系统.
首先,查看系统是否支持cpuset子系统,也就是看内核编译选项CONFIG_CPUSETS是否设为y
我的测试系统是支持的,如果你的系统不支持,就需要重新编译内核了.......
然后,用下面的例子演示将A和B中的stress都指定到1个CPU上后的情况
卸载当前的cgroup
再次挂载cgroup文件系统,并指定-ocpuset
指定A的物理CPU为0(双核CPU的每个核编号分别是CPU0,CPU1)
指定B的物理CPU也为0
重复实例1中的步骤,观察发生的变化
如果出现上述错误,只需要再设置/mnt/cgroup/A/cpuset.mems即可.(参考:http://serverfault.com/questions/579555/cgroup-no-space-left-on-device)
从上面的结果可以看出,虽然stress命令指定了-c2(意思是在2个CPU上运行),但是由于A和B都只绑定了CPU0,
所以虽然是双核的机器,它们所占用的CPU总量却只有100%,而不是实例1中的200%.
如果将B组的物理CPU绑定到CPU1,那么应该所有stress的进程都占用50%,CPU资源的总量变为200%.
下面将B组的物理CPU绑定为CPU1,看看结果是否和我们的预期一样.
果然,和预期一致.A组中的stress和B组中的stress在各自的物理CPU上都占用了100%左右的CPU使用率.
实例4-cgroup对使用的内存的控制
cgroup对内存的控制也很简单,只要挂载cgroup时,指定-omemory
出现以上错误的原因可能是因为debian系统中,默认没有启动cgroup的memory子系统.可以通过以下方法确认:
为了默认启用memory子系统,可以设置grub选项
重启之后,发现/proc/cgroups中的memory已经enabled,并且也可以挂载memcg了
开始实验:
重启系统(为了保证内存的干净)
挂载memcg
在挂载的/mnt/cgroup中创建组A
将当前shell加入到组A
不限制组A的内存,压缩内核源码包,并观察压缩前后内存的变化
重复步骤1~4
限制组A的内存为10MB,再次压缩内核源码包,并观察压缩前后内存的变化
从上面的结果可以看出限制内存是起了作用的.
不限制内存时,tar压缩前后buffer+cache内存从(9MB+43MB)==>(26MB+1614MB)增大了1588MB
限制内存后,tar压缩前后buffer+cache内存从(10MB+43MB)==>(14MB+48MB)增大了9MB
CPU资源控制
每个进程能够占用CPU多长时间,什么时候能够占用CPU是和系统的调度密切相关的.Linux系统中有多种调度策略,各种调度策略有其适用的场景,也很难说哪种调度策略是最优的.
Linux的调度策略可以参见代码:include/linux/sched.h
/* *Schedulingpolicies */ #defineSCHED_NORMAL0 #defineSCHED_FIFO1 #defineSCHED_RR2 #defineSCHED_BATCH3 /*SCHED_ISO:reservedbutnotimplementedyet*/ #defineSCHED_IDLE5 /*CanbeORedintomakesuretheprocessisrevertedbacktoSCHED_NORMALonfork*/ #defineSCHED_RESET_ON_FORK0x40000000
Linux系统也提供了修改调度策略的命令和系统调用接口.
调用接口请查询相关文档,这里主要介绍一下修改调度策略的命令-chrt.
#在一个终端中执行 sleep1000 #打开另一个终端 ps-ef|grepsleep#找出sleep1000的pid,这里假设是1234 chrt-p1234#可以查看pid=1234的进程的调度策略,输入如下: pid1234'scurrentschedulingpolicy:SCHED_OTHER pid1234'scurrentschedulingpriority:0 chrt-p-f101234#修改调度策略为SCHED_FIFO,并且优先级为10 chrt-p1234#再次查看调度策略 pid1234'scurrentschedulingpolicy:SCHED_FIFO pid1234'scurrentschedulingpriority:10
补充:
chrt也可以直接指定一条命令,并设置这条命令的优先级的调度策略,具体查看chrt--help
查看一个进程的调度策略,除了使用chrt命令之外,还可以cat/proc/<PID>/sched
实时进程的CPU控制
所谓的实时进程,也就是那些对响应时间要求比较高的进程.这类进程需要在限定的时间内处理用户的请求,因此,在限定的这段时间内,需要占用所有CPU资源,并且不能被其它进程打断.
在这种情况下,如果实时进程中出现了类似死循环之类的情况,就会导致整个系统无响应.
因为实时进程的CPU优先级高,并且未处理完之前是不会释放CPU资源的.
所以,内核中需要有一种方式来限制实时进程的CPU资源占用.
系统整体设置
1.获取当前系统的设置sysctl-nkernel.sched_rt_period_us#实时进程调度的单位CPU时间1秒 1000000 sysctl-nkernel.sched_rt_runtime_us#实时进程在1秒中实际占用的CPU时间,0.95秒 950000
这个设置说明实时进程在运行时并不是完全占用CPU的,每1秒中有0.05秒的时间可以给其它进程运行.
这样既不会对实时进程的响应时间造成太大的影响,也避免了实时进程卡住时导致整个系统无响应.
2.设置实时进程占用CPU时间
上面的默认设置中,实时进程占用95%的CPU时间.如果觉得占用的太多或太少,都是可以调整的.比如:
sysctl-wkernel.sched_rt_runtime_us=900000#设置实时进程每1秒中只占0.9秒的CPU时间 kernel.sched_rt_runtime_us=900000 sysctl-nkernel.sched_rt_runtime_us 900000
cgroup中的设置
整体设置是针对整个系统的,我们也可以通过cgroup来对一组进程的CPU资源进行控制.如果想在cgroup中对sched_rt_period_us和sched_rt_runtime_us进行控制,需要内核编译选项CONFIG_RT_GROUP_SCHED=y
查看当前系统的内核编译选项方法如下:(debian7.6系统)
cat/boot/config-`uname-r`
查看CONFIG_RT_GROUP_SCHED是否启用
cat/boot/config-`uname-r`|grep-irt_group #CONFIG_RT_GROUP_SCHEDisnotset
debian7.6默认没有启动这个选项,所以挂载cgroup之后,没有设置sched_rt_period_us和sched_rt_runtime_us的文件
mkdir/mnt/cgroup mount-tcgroupcgroup/mnt/cgroup/ cd/mnt/cgroup/ ls-l total0 -r--r--r--1rootroot0Aug2809:06blkio.io_merged -r--r--r--1rootroot0Aug2809:06blkio.io_queued -r--r--r--1rootroot0Aug2809:06blkio.io_service_bytes -r--r--r--1rootroot0Aug2809:06blkio.io_serviced -r--r--r--1rootroot0Aug2809:06blkio.io_service_time -r--r--r--1rootroot0Aug2809:06blkio.io_wait_time --w-------1rootroot0Aug2809:06blkio.reset_stats -r--r--r--1rootroot0Aug2809:06blkio.sectors -r--r--r--1rootroot0Aug2809:06blkio.time -rw-r--r--1rootroot0Aug2809:06blkio.weight -rw-r--r--1rootroot0Aug2809:06blkio.weight_device -rw-r--r--1rootroot0Aug2809:06cgroup.clone_children --w--w--w-1rootroot0Aug2809:06cgroup.event_control -rw-r--r--1rootroot0Aug2809:06cgroup.procs -r--r--r--1rootroot0Aug2809:06cpuacct.stat -rw-r--r--1rootroot0Aug2809:06cpuacct.usage -r--r--r--1rootroot0Aug2809:06cpuacct.usage_percpu -rw-r--r--1rootroot0Aug2809:06cpuset.cpu_exclusive -rw-r--r--1rootroot0Aug2809:06cpuset.cpus -rw-r--r--1rootroot0Aug2809:06cpuset.mem_exclusive -rw-r--r--1rootroot0Aug2809:06cpuset.mem_hardwall -rw-r--r--1rootroot0Aug2809:06cpuset.memory_migrate -r--r--r--1rootroot0Aug2809:06cpuset.memory_pressure -rw-r--r--1rootroot0Aug2809:06cpuset.memory_pressure_enabled -rw-r--r--1rootroot0Aug2809:06cpuset.memory_spread_page -rw-r--r--1rootroot0Aug2809:06cpuset.memory_spread_slab -rw-r--r--1rootroot0Aug2809:06cpuset.mems -rw-r--r--1rootroot0Aug2809:06cpuset.sched_load_balance -rw-r--r--1rootroot0Aug2809:06cpuset.sched_relax_domain_level -rw-r--r--1rootroot0Aug2809:06cpu.shares --w-------1rootroot0Aug2809:06devices.allow --w-------1rootroot0Aug2809:06devices.deny -r--r--r--1rootroot0Aug2809:06devices.list -rw-r--r--1rootroot0Aug2809:06net_cls.classid -rw-r--r--1rootroot0Aug2809:06notify_on_release -rw-r--r--1rootroot0Aug2809:06release_agent -rw-r--r--1rootroot0Aug2809:06tasks
果然,只有cpu.share,没有cpu.sched_rt_period_us和cpu.sched_rt_runtime_us
没办法,重新编译内核,编译内核的具体方法参见:
为了节约时间,我们用makelocalmodconfig来创建.config文件,然后修改其中的CONFIG_RT_GROUP_SCHED=y
下载源码等等参见:
cd/path/to/linux-source-3.2 makelocalmodconfig vim.config#设置CONFIG_RT_GROUP_SCHED=y并保存 make makemodules_install makeinstall reboot#重启之前看看/boot/grub/grub.cfg中,默认启动的是不是新安装的内核
启动到新内核,再次查看内核选项CONFIG_RT_GROUP_SCHED是否启用
cat/boot/config-`uname-r`|grep-irt_group
CONFIG_RT_GROUP_SCHED=y#已启用
再次挂载cgroup文件系统,发现多了2个配置文件,cpu.rt_period_us和cpu.rt_runtime_us
mount-tcgroupcgroup/mnt/cgroup/
cd/mnt/cgroup/
ls-l
total0
-r--r--r--1rootroot0Aug2809:53blkio.io_merged
-r--r--r--1rootroot0Aug2809:53blkio.io_queued
-r--r--r--1rootroot0Aug2809:53blkio.io_service_bytes
-r--r--r--1rootroot0Aug2809:53blkio.io_serviced
-r--r--r--1rootroot0Aug2809:53blkio.io_service_time
-r--r--r--1rootroot0Aug2809:53blkio.io_wait_time
--w-------1rootroot0Aug2809:53blkio.reset_stats
-r--r--r--1rootroot0Aug2809:53blkio.sectors
-r--r--r--1rootroot0Aug2809:53blkio.time
-rw-r--r--1rootroot0Aug2809:53blkio.weight
-rw-r--r--1rootroot0Aug2809:53blkio.weight_device
-rw-r--r--1rootroot0Aug2809:53cgroup.clone_children
--w--w--w-1rootroot0Aug2809:53cgroup.event_control
-rw-r--r--1rootroot0Aug2809:53cgroup.procs
-r--r--r--1rootroot0Aug2809:53cpuacct.stat
-rw-r--r--1rootroot0Aug2809:53cpuacct.usage
-r--r--r--1rootroot0Aug2809:53cpuacct.usage_percpu
-rw-r--r--1rootroot0Aug2809:53cpu.rt_period_us
-rw-r--r--1rootroot0Aug2809:53cpu.rt_runtime_us
-rw-r--r--1rootroot0Aug2809:53cpuset.cpu_exclusive
-rw-r--r--1rootroot0Aug2809:53cpuset.cpus
-rw-r--r--1rootroot0Aug2809:53cpuset.mem_exclusive
-rw-r--r--1rootroot0Aug2809:53cpuset.mem_hardwall
-rw-r--r--1rootroot0Aug2809:53cpuset.memory_migrate
-r--r--r--1rootroot0Aug2809:53cpuset.memory_pressure
-rw-r--r--1rootroot0Aug2809:53cpuset.memory_pressure_enabled
-rw-r--r--1rootroot0Aug2809:53cpuset.memory_spread_page
-rw-r--r--1rootroot0Aug2809:53cpuset.memory_spread_slab
-rw-r--r--1rootroot0Aug2809:53cpuset.mems
-rw-r--r--1rootroot0Aug2809:53cpuset.sched_load_balance
-rw-r--r--1rootroot0Aug2809:53cpuset.sched_relax_domain_level
-rw-r--r--1rootroot0Aug2809:53cpu.shares
--w-------1rootroot0Aug2809:53devices.allow
--w-------1rootroot0Aug2809:53devices.deny
-r--r--r--1rootroot0Aug2809:53devices.list
-rw-r--r--1rootroot0Aug2809:53net_cls.classid
-rw-r--r--1rootroot0Aug2809:53notify_on_release
-rw-r--r--1rootroot0Aug2809:53release_agent
-rw-r--r--1rootroot0Aug2809:53tasks
catcpu.rt_period_us
1000000
catcpu.rt_runtime_us
950000
通过配置cpu.rt_period_us和cpu.rt_runtime_us就可以对cgroup中的进程组中的实时进程进行CPU使用时间的控制.
资源控制实例
上面主要介绍资源的一些理论基础,下面通过一些实例演示如果通过cgroup来控制进程所使用的CPU和内存资源.Linux对CPU和内存的控制有对应的cgroup子系统cpuset和memory
实例:cgroup中对其中*子cgroup*的CPU资源控制
对各个*子cgroup*的CPU占用率进行控制主要依靠每个*子cgroup*的cpu.shares文件直接用实验过程来说话,其中加入了一些注释.
#安装需要的软件
apt-getinstallstress#让CPU达到100%的压力工具
apt-getinstallsysstat#查看系统CPU,内存,磁盘,网络等资源使用情况的工具
实例1-默认情况,A和B各占CPU总资源的1/2
挂载cgroup文件系统(注意加上-ocpu的选项)
在cgroup中创建2个子cgroupA和B
默认情况下,cgroupA和cgroupB中的cpu.shares中的数值都是1024
在A和B中用stress工具使其CPU占用率达到100%
top命令查看A和B中进程分别占用的CPU(应该都是50%)
#挂载cgroup文件系统
mount-tcgroup-ocpucgroup/mnt/cgroup/
cd/mnt/cgroup
ls-l
total0
-r--r--r--1rootroot0Aug2811:29blkio.io_merged
-r--r--r--1rootroot0Aug2811:29blkio.io_queued
-r--r--r--1rootroot0Aug2811:29blkio.io_service_bytes
-r--r--r--1rootroot0Aug2811:29blkio.io_serviced
-r--r--r--1rootroot0Aug2811:29blkio.io_service_time
-r--r--r--1rootroot0Aug2811:29blkio.io_wait_time
--w-------1rootroot0Aug2811:29blkio.reset_stats
-r--r--r--1rootroot0Aug2811:29blkio.sectors
-r--r--r--1rootroot0Aug2811:29blkio.time
-rw-r--r--1rootroot0Aug2811:29blkio.weight
-rw-r--r--1rootroot0Aug2811:29blkio.weight_device
-rw-r--r--1rootroot0Aug2811:29cgroup.clone_children
--w--w--w-1rootroot0Aug2811:29cgroup.event_control
-rw-r--r--1rootroot0Aug2811:29cgroup.procs
-r--r--r--1rootroot0Aug2811:29cpuacct.stat
-rw-r--r--1rootroot0Aug2811:29cpuacct.usage
-r--r--r--1rootroot0Aug2811:29cpuacct.usage_percpu
-rw-r--r--1rootroot0Aug2811:29cpuset.cpu_exclusive
-rw-r--r--1rootroot0Aug2811:29cpuset.cpus
-rw-r--r--1rootroot0Aug2811:29cpuset.mem_exclusive
-rw-r--r--1rootroot0Aug2811:29cpuset.mem_hardwall
-rw-r--r--1rootroot0Aug2811:29cpuset.memory_migrate
-r--r--r--1rootroot0Aug2811:29cpuset.memory_pressure
-rw-r--r--1rootroot0Aug2811:29cpuset.memory_pressure_enabled
-rw-r--r--1rootroot0Aug2811:29cpuset.memory_spread_page
-rw-r--r--1rootroot0Aug2811:29cpuset.memory_spread_slab
-rw-r--r--1rootroot0Aug2811:29cpuset.mems
-rw-r--r--1rootroot0Aug2811:29cpuset.sched_load_balance
-rw-r--r--1rootroot0Aug2811:29cpuset.sched_relax_domain_level
-rw-r--r--1rootroot0Aug2811:29cpu.shares
--w-------1rootroot0Aug2811:29devices.allow
--w-------1rootroot0Aug2811:29devices.deny
-r--r--r--1rootroot0Aug2811:29devices.list
-rw-r--r--1rootroot0Aug2811:29net_cls.classid
-rw-r--r--1rootroot0Aug2811:29notify_on_release
-rw-r--r--1rootroot0Aug2811:29release_agent
-rw-r--r--1rootroot0Aug2811:29tasks
#创建子cgroupA和B
mkdir{A,B}
catA/cpu.shares
1024
catB/cpu.shares
1024
#在A和B中分别通过stress工具使其CPU使用率达到100%
echo$$>A/tasks#将当前的SHELL加入到cgroupA中
stress-c2#这里-c2是因为测试机器是双核,要在2个核上都产生100%的CPU占用率
#另外打开一个shell窗口,并将这个shell加入到cgroupB中
echo$$>B/tasks#将当前的SHELL加入到cgroupB中
stress-c2#在2个核上都产生100%的CPU占用率
#再打开一个shell窗口,用top命令查看CPU占用情况
top
top-14:10:32up43min,3users,loadaverage:2.31,1.24,0.62
Tasks:78total,5running,73sleeping,0stopped,0zombie
%Cpu(s):100.0us,0.0sy,0.0ni,0.0id,0.0wa,0.0hi,0.0si,0.0st
KiBMem:1887872total,114744used,1773128free,10472buffers
KiBSwap:3982332total,0used,3982332free,45068cached
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
3350root2006524920R49.90.00:08.73stress
3351root2006524920R49.90.00:08.67stress
3353root2006524920R49.90.00:07.35stress
3354root2006524920R49.90.00:07.36stress
#查看这4个stress进程是否分别属于A和B
cat/mnt/cgroup/A/tasks
2945
3349
3350<--stress进程
3351<--stress进程
cat/mnt/cgroup/B/tasks
2996
3352
3353<--stress进程
3354<--stress进程
可以看出,A和B组中的2个stress进程的CPU使用率相加都是100%,
由于我测试的电脑是双核,top所看到的CPU最大使用率是200%,所以和预期一致,A和B组各占CPU总资源的1/2
实例2-Agroup占用整体CPU资源的2/3,Bgroup占用整体CPU资源的1/3
环境同实例1,不再重新挂载cgroup文件系统,也不在重建A和B
Agroup的cpu.shares文件不变,值为1024
Bgroup的cpu.shares文件中的值改为512,这样,相当于B占用CPU总资源的1/3(因为512/(512+1024)=1/3)
同实例1,通过2个shell窗口,分别是A和B的CPU使用率达到100%,然后通过top查看CPU使用情况
#在B中shell窗口执行以下命令
catB/cpu.shares
1024
echo512>B/cpu.shares
catB/cpu.shares
512
stress-c2
#在A中shell窗口执行以下命令
stress-c2
#在第3个shell窗口,也就是非A,非B的那个shell窗口,用top查看cpu使用情况
top
top-14:13:18up46min,3users,loadaverage:2.24,1.92,1.01
Tasks:78total,5running,73sleeping,0stopped,0zombie
%Cpu(s):100.0us,0.0sy,0.0ni,0.0id,0.0wa,0.0hi,0.0si,0.0st
KiBMem:1887872total,114744used,1773128free,10488buffers
KiBSwap:3982332total,0used,3982332free,45068cached
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
3376root2006524880R66.60.00:06.29stress
3377root2006524880R66.60.00:06.30stress
3373root2006524880R33.30.00:04.33stress
3374root2006524880R33.30.00:04.32stress
#查看这4个stress进程是否分别属于A和B
cat/mnt/cgroup/A/tasks
2945
3375
3376<--stress进程
3377<--stress进程
cat/mnt/cgroup/B/tasks
2996
3372
3373<--stress进程
3374<--stress进程
很明显,A组中的2个进程占用了CPU总量的2/3左右,B组中的2个进程占用了CPU总量的1/3左右.
实例3-物理CPU的控制
上面的实例中,虽然能够控制每个组的CPU的总体占用率,但是不能控制某个组的进程固定在某个物理CPU上运行.
要想将cgroup绑定到某个固定的CPU上,需要使用cpuset子系统.
首先,查看系统是否支持cpuset子系统,也就是看内核编译选项CONFIG_CPUSETS是否设为y
cat/boot/config-`uname-r`|grep-icpusets
CONFIG_CPUSETS=y
我的测试系统是支持的,如果你的系统不支持,就需要重新编译内核了.......
然后,用下面的例子演示将A和B中的stress都指定到1个CPU上后的情况
卸载当前的cgroup
再次挂载cgroup文件系统,并指定-ocpuset
指定A的物理CPU为0(双核CPU的每个核编号分别是CPU0,CPU1)
指定B的物理CPU也为0
重复实例1中的步骤,观察发生的变化
umount/mnt/cgroup
mount-tcgroup-ocpusetcgroup/mnt/cgroup/
cd/mnt/cgroup
ls-l
total0
-rw-r--r--1rootroot0Aug2814:39cgroup.clone_children
--w--w--w-1rootroot0Aug2814:39cgroup.event_control
-rw-r--r--1rootroot0Aug2814:39cgroup.procs
-rw-r--r--1rootroot0Aug2814:39cpuset.cpu_exclusive
-rw-r--r--1rootroot0Aug2814:39cpuset.cpus<--这个就是设置关联物理CPU的文件
-rw-r--r--1rootroot0Aug2814:39cpuset.mem_exclusive
-rw-r--r--1rootroot0Aug2814:39cpuset.mem_hardwall
-rw-r--r--1rootroot0Aug2814:39cpuset.memory_migrate
-r--r--r--1rootroot0Aug2814:39cpuset.memory_pressure
-rw-r--r--1rootroot0Aug2814:39cpuset.memory_pressure_enabled
-rw-r--r--1rootroot0Aug2814:39cpuset.memory_spread_page
-rw-r--r--1rootroot0Aug2814:39cpuset.memory_spread_slab
-rw-r--r--1rootroot0Aug2814:39cpuset.mems
-rw-r--r--1rootroot0Aug2814:39cpuset.sched_load_balance
-rw-r--r--1rootroot0Aug2814:39cpuset.sched_relax_domain_level
-rw-r--r--1rootroot0Aug2814:39notify_on_release
-rw-r--r--1rootroot0Aug2814:39release_agent
-rw-r--r--1rootroot0Aug2814:39tasks
#创建子cgroupA和B
mkdir{A,B}
catA/cpuset.cpus
<--默认是空的
echo0>A/cpuset.cpus
catA/cpuset.cpus
0
echo0>B/cpuset.cpus#同样,设置B组也绑定到CPU0
#当前Shell加入到A组
echo$$>/mnt/cgroup/A/tasks
-bash:echo:writeerror:Nospaceleftondevice
如果出现上述错误,只需要再设置/mnt/cgroup/A/cpuset.mems即可.(参考:
#同时设置A的cpuset.cpus和cpuset.mems
echo0>A/cpuset.cpus
echo0>A/cpuset.mems
#B组也同样设置
echo0>B/cpuset.cpus
echo0>B/cpuset.mems
#将当前shell加入到A组
echo$$>/mnt/cgroup/A/tasks<--设置过cpuset.mems后,就没有出错了
stress-c2
#再打开一个Shell窗口,并加入到B组
echo$$>/mnt/cgroup/B/tasks
stress-c2
#再打开第3个shell窗口,用top命令查看CPU使用情况
top
top-15:13:29up1:46,3users,loadaverage:1.01,0.24,0.12
Tasks:78total,5running,73sleeping,0stopped,0zombie
%Cpu(s):50.0us,0.0sy,0.0ni,50.0id,0.0wa,0.0hi,0.0si,0.0st
KiBMem:1887872total,117216used,1770656free,11144buffers
KiBSwap:3982332total,0used,3982332free,47088cached
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
3830root2006524920R25.00.00:04.96stress
3831root2006524920R25.00.00:04.97stress
3834root2006524920R25.00.00:03.56stress
3833root2006524920R24.60.00:03.56stress
从上面的结果可以看出,虽然stress命令指定了-c2(意思是在2个CPU上运行),但是由于A和B都只绑定了CPU0,
所以虽然是双核的机器,它们所占用的CPU总量却只有100%,而不是实例1中的200%.
如果将B组的物理CPU绑定到CPU1,那么应该所有stress的进程都占用50%,CPU资源的总量变为200%.
下面将B组的物理CPU绑定为CPU1,看看结果是否和我们的预期一样.
#在B组的shell窗口中执行以下命令
echo1>/mnt/cgroup/B/cpuset.cpus
cat/mnt/cgroup/B/cpuset.cpus
1
stress-c2
#在A组的shell窗口中执行以下命令
stress-c2
#在第3个shell窗口中用top命令查看执行结果
top
top-15:20:07up1:53,3users,loadaverage:0.38,0.83,0.56
Tasks:78total,5running,73sleeping,0stopped,0zombie
%Cpu(s):100.0us,0.0sy,0.0ni,0.0id,0.0wa,0.0hi,0.0si,0.0st
KiBMem:1887872total,117340used,1770532free,11168buffers
KiBSwap:3982332total,0used,3982332free,47088cached
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
3854root2006524880R49.90.00:03.76stress
3857root2006524920R49.90.00:02.29stress
3858root2006524920R49.90.00:02.29stress
3855root2006524880R49.60.00:03.76stress
果然,和预期一致.A组中的stress和B组中的stress在各自的物理CPU上都占用了100%左右的CPU使用率.
实例4-cgroup对使用的内存的控制
cgroup对内存的控制也很简单,只要挂载cgroup时,指定-omemory
#首先之前挂载的cpuset子系统
umount/mnt/cgroup
#挂载cgroup文件系统,指定-omemeory
mount-omemory-tcgroupmemcg/mnt/cgroup/
mount:specialdevicememcgdoesnotexist
出现以上错误的原因可能是因为debian系统中,默认没有启动cgroup的memory子系统.可以通过以下方法确认:
cat/proc/cgroups
#subsys_namehierarchynum_cgroupsenabled
cpuset011
cpu011
cpuacct011
memory110<--这里的enabled是0
devices011
freezer011
net_cls011
blkio011
perf_event011
为了默认启用memory子系统,可以设置grub选项
vim/etc/default/grub
#修改GRUB_CMDLINE_LINUX=""==>GRUB_CMDLINE_LINUX="cgroup_enable=memory"
#保存后,更新grub.cfg
update-grub
reboot
重启之后,发现/proc/cgroups中的memory已经enabled,并且也可以挂载memcg了
cat/proc/cgroups
#subsys_namehierarchynum_cgroupsenabled
cpuset011
cpu011
cpuacct011
memory111
devices011
freezer011
net_cls011
blkio011
perf_event011
#挂载cgroup的memory子系统
mount-tcgroup-omemorymemcg/mnt/cgroup
ls-l/mnt/cgroup/<--可以看到有很多memory相关的配置
total0
-rw-r--r--1rootroot0Aug2815:54cgroup.clone_children
--w--w--w-1rootroot0Aug2815:54cgroup.event_control
-rw-r--r--1rootroot0Aug2815:54cgroup.procs
-rw-r--r--1rootroot0Aug2815:54memory.failcnt
--w-------1rootroot0Aug2815:54memory.force_empty
-rw-r--r--1rootroot0Aug2815:54memory.limit_in_bytes<--限制内存使用的配置文件
-rw-r--r--1rootroot0Aug2815:54memory.max_usage_in_bytes
-rw-r--r--1rootroot0Aug2815:54memory.move_charge_at_immigrate
-r--r--r--1rootroot0Aug2815:54memory.numa_stat
-rw-r--r--1rootroot0Aug2815:54memory.oom_control
-rw-r--r--1rootroot0Aug2815:54memory.soft_limit_in_bytes
-r--r--r--1rootroot0Aug2815:54memory.stat
-rw-r--r--1rootroot0Aug2815:54memory.swappiness
-r--r--r--1rootroot0Aug2815:54memory.usage_in_bytes
-rw-r--r--1rootroot0Aug2815:54memory.use_hierarchy
-rw-r--r--1rootroot0Aug2815:54notify_on_release
-rw-r--r--1rootroot0Aug2815:54release_agent
-rw-r--r--1rootroot0Aug2815:54tasks
开始实验:
重启系统(为了保证内存的干净)
挂载memcg
在挂载的/mnt/cgroup中创建组A
将当前shell加入到组A
不限制组A的内存,压缩内核源码包,并观察压缩前后内存的变化
重复步骤1~4
限制组A的内存为10MB,再次压缩内核源码包,并观察压缩前后内存的变化
#重启系统
reboot
#挂载memcg
mount-tcgroup-omemorymemcg/mnt/cgroup
#创建组A
mkdir/mnt/cgroup/A
#将当前shell加入到组A
echo$$>/mnt/cgroup/A/tasks
#测试不限制内存时,内存的使用情况,这里不用linux源码也可以,但最好用个大点的文件夹来压缩,以便更容易看出内存的变化.
free-m;tarczvflinux-source-3.2.tar.gz/path/to/linux-source-3.2/>/dev/null;free-m;
totalusedfreesharedbufferscached
Mem:184312217210943
-/+buffers/cache:681774
Swap:388803888
totalusedfreesharedbufferscached
Mem:18431744990261614
-/+buffers/cache:1041739
Swap:388803888
#重启系统
reboot
#挂载memcg
mount-tcgroup-omemorymemcg/mnt/cgroup
#创建组A
mkdir/mnt/cgroup/A
#将当前shell加入到组A
echo$$>/mnt/cgroup/A/tasks
#限制组A的内存使用量最大为10MB
echo10M>/mnt/cgroup/A/memory.limit_in_bytes
#测试限制内存为10MB时,内存的使用情况.
rm-rflinux-source-3.2.tar.gz
free-m;tarczvflinux-source-3.2.tar.gz/path/to/linux-source-3.2/>/dev/null;free-m;
totalusedfreesharedbufferscached
Mem:1843122172101043
-/+buffers/cache:681774
Swap:388803888
totalusedfreesharedbufferscached
Mem:1843194164901448
-/+buffers/cache:1311712
Swap:388803888
从上面的结果可以看出限制内存是起了作用的.
不限制内存时,tar压缩前后buffer+cache内存从(9MB+43MB)==>(26MB+1614MB)增大了1588MB
限制内存后,tar压缩前后buffer+cache内存从(10MB+43MB)==>(14MB+48MB)增大了9MB
相关文章推荐
- linux部署计划任务
- linux虚拟文件系统2
- linux 虚拟文件系统
- linux命令---常用stty的命令
- Linux软连接和硬链接
- 关于Linux session管理与GUI架构
- linux下syscall函数,SYS_gettid
- 解决方案: scp/ssh 的登陆提示很慢 (Linux)
- linux 安装 lrzsz
- Linux命令--- /dev/null和/dev/tty
- linux---正则表达式
- Linux升级openssh及问题总结
- linux命令---wc
- linux命令---head与tail
- 主要的中断下半部及其区别
- Linux 内核配置机制(make menuconfig、Kconfig、makefile)讲解
- linux 下共享内存shm详解
- linux中fork()函数详解
- 几个常用的Linux监控脚本
- Linux source code Makefile分析