签到成功

知道了

CNDBA社区CNDBA社区

cgroup控制cpu,io,memory测试说明

2016-10-21 20:17 4146 0 原创 Linux
作者: Expect-乐

1.cgroup介绍

  cgroup是control group的简称,它为Linux内核提供了一种任务聚集和划分的机制,通过一组参数集合将

一些任务组织成一个或多个子系统。

 子系统是根据cgroup对任务的划分功能将任务按照一种指定的属性划分成的一个组,主要用来实现资源的控制。

在cgroup中,划分成的任务组以层次结构的形式组织,多个子系统形成一个数据结构中类似多根树的结构。

cgroup包含了多个孤立的子系统,每一个子系统代表单一的资源,目前,redhat默认支持10个子系统,

但默认只挂载了8个子系统,ubuntu 12.04 默认支持8个子系统,但默认只挂载了5个子系统。

1.1.CGroup 功能及组成

CGroup 是将任意进程进行分组化管理的 Linux 内核功能。CGroup 本身是提供将进程进行分组化管理的功能和接口的基础结构,http://www.cndba.cn/Expect-le/article/298

I/O 或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。这些具体的资源管理功能称为 CGroup 子系统或控制器。

CGroup 子系统有控制内存的 Memory 控制器、控制进程调度的 CPU 控制器等。运行中的内核可以使用的 Cgroup 子系统由/proc/cgroup 来确认。http://www.cndba.cn/Expect-le/article/298

1.2.cgroup子系统介绍

当然也用户可以自定义子系统并进行挂载。


下面对每一个子系统进行简单的介绍:


1)blkio 设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb等等。

2)cpu 使用调度程序为cgroup任务提供cpu的访问。

3)cpuacct 产生cgroup任务的cpu资源报告。

4)cpuset 如果是多核心的cpu,这个子系统会为cgroup任务分配单独的cpu和内存。

5)devices 允许或拒绝cgroup任务对设备的访问。

6)freezer 暂停和恢复cgroup任务。http://www.cndba.cn/Expect-le/article/298

7)memory 设置每个cgroup的内存限制以及产生内存资源报告。

8)net_cls 标记每个网络包以供cgroup方便使用。

9)ns 名称空间子系统。

10)perf_event 增加了对每group的监测跟踪的能力,即可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程,http://www.cndba.cn/Expect-le/article/298

此功能对于监测整个group非常有用,具体参见 http://lwn.net/Articles/421574/

1.3.CGroup 支持的文件种类

 CGroup 支持的文件种类

文件名             R/W    用途

Release_agent        RW    删除分组时执行的命令,这个文件只存在于根分组

Notify_on_release    RW    设置是否执行 release_agent。为 1 时执行

Tasks                RW    属于分组的线程 TID 列表

Cgroup.procs         R     属于分组的进程 PID 列表。仅包括多线程进程的线程 leader 的 TID,这点与 tasks 不同

Cgroup.event_control RW    监视状态变化和分组删除事件的配置文件

1.4.CGroup 相关概念解释

任务(task)。在 cgroups 中,任务就是系统的一个进程;

控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。

一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。

一个进程组的进程可以使用 cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制;

层级(hierarchy)。控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。

控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性;

子系统(subsystem)。一个子系统就是一个资源控制器,比如 cpu 子系统就是控制 cpu 时间分配的一个控制器。

子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,

这个层级上的所有控制族群都受到这个子系统的控制。

2.libcgroup安装

#安装

redhat系统:

yum install libcgroup

ubuntu系统: 

sudo apt-get install cgroup-bin

#cgroup服务的启动和停止,重启:

service cgconfig start|stop|restart

#开机启动

chkconfig cgconfig on

#可以看到cgroup子系统

[root@node3 ~]# cat /etc/system-release
Red Hat Enterprise Linux Server release 6.7 (Santiago)

Red Hat默认挂载八个子系统。可以通过配置文件修改挂载的子系统。

[root@dg1 ~]# ls /cgroup/
blkio  cpu  cpuacct  cpuset  devices  freezer  memory  net_cls

#查看配置文件,可以看到mount了八个子系统

[root@node3 ~]# cat /etc/cgconfig.conf 
#
#  Copyright IBM Corporation. 2007
#
#  Authors:Balbir Singh <balbir@linux.vnet.ibm.com>
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of version 2.1 of the GNU Lesser General Public License
#  as published by the Free Software Foundation.
#
#  This program is distributed in the hope that it would be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See man cgconfig.conf for further details.
#
# By default, mount all controllers to /cgroup/<controller>
mount {
cpuset= /cgroup/cpuset;
cpu= /cgroup/cpu;
cpuacct= /cgroup/cpuacct;
memory= /cgroup/memory;
devices= /cgroup/devices;
freezer= /cgroup/freezer;
net_cls= /cgroup/net_cls;
blkio= /cgroup/blkio;
}

删除blkio = /cgroup/blkio;试试,看看啥效果

#删除之前,文件夹里有各种各样的配置文件

[root@node3 ~]# ll /cgroup/blkio/
total 0
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.io_merged
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.io_queued
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.io_service_bytes
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.io_serviced
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.io_service_time
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.io_wait_time
--w------- 1 root root 0 Oct 21 05:15 blkio.reset_stats
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.sectors
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.throttle.io_service_bytes
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.throttle.io_serviced
-rw-r--r-- 1 root root 0 Oct 21 05:15 blkio.throttle.read_bps_device
-rw-r--r-- 1 root root 0 Oct 21 05:15 blkio.throttle.read_iops_device
-rw-r--r-- 1 root root 0 Oct 21 05:15 blkio.throttle.write_bps_device
-rw-r--r-- 1 root root 0 Oct 21 05:15 blkio.throttle.write_iops_device
-r--r--r-- 1 root root 0 Oct 21 05:15 blkio.time
-rw-r--r-- 1 root root 0 Oct 21 05:15 blkio.weight
-rw-r--r-- 1 root root 0 Oct 21 05:15 blkio.weight_device
--w--w--w- 1 root root 0 Oct 21 05:15 cgroup.event_control
-rw-r--r-- 1 root root 0 Oct 21 05:15 cgroup.procs
-rw-r--r-- 1 root root 0 Oct 21 05:15 notify_on_release
-rw-r--r-- 1 root root 0 Oct 21 05:15 release_agent
-rw-r--r-- 1 root root 0 Oct 21 05:15 tasks

#删除以后,重启一下,啥也没有了。

[root@node3 ~]# service cgconfig restart
Stopping cgconfig service:                                 [  OK  ]
Starting cgconfig service:                                 [  OK  ]
[root@node3 ~]# ll /cgroup/blkio/
total 0

cgroup启动时,会读取配置文件/etc/cgconfig.conf的内容,根据其内容创建和挂载指定的cgroup子系统。

主要由mount和group两个section构成。http://www.cndba.cn/Expect-le/article/298

(1)mount section的语法格式如下:


mount {
    <controller> = <path>;
    ...
}

#########################################

# controller:内核子系统的名称

# path:该子系统的挂载点

#########################################

举个例子:


mount {
    cpuset = /cgroup/red;
}

上面定义相当于如下shell指令:


mkdir /cgroup/red
mount -t cgroup -o cpuset red /cgroup/red

(2)group section的语法格式如下:


group <name> {
    [<permissions>]
    <controller> {
        <param name> = <param value>;
        …
    }
    …
}

################################################################################

## name: 指定cgroup的名称

## permissions:可选项,指定cgroup对应的挂载点文件系统的权限,root用户拥有所有权限。

## controller:子系统的名称

http://www.cndba.cn/Expect-le/article/298

## param name 和 param value:子系统的属性及其属性值

#################################################################################

举个例子:


mount {  ## 定义需要创建的cgroup子系统及其挂载点,这里创建cpu与cpuacct(统计)两个cgroup子系统
cpu = /mnt/cgroups/cpu;
cpuacct = /mnt/cgroups/cpu;
}
group daemons/www { ## 定义daemons/www(web服务器进程)组
perm {      ## 定义这个组的权限
task {
uid = root;
gid = webmaster;
                }
                admin {
                uid = root;
                        gid = root;
                }
            }
        cpu {      ## 定义cpu子系统的属性及其值,即属于词组的任务的权重为1000
        cpu.shares = 1000;
            }
}
group daemons/ftp { ## 定义daemons/ftp(ftp进程)组
perm {
task {
uid = root;
gid = ftpmaster;
                     }
admin {
uid = root;
gid = root;
}
}
        cpu {  ## 定义词组的任务的权重为500
        cpu.shares = 500;
        }
}

上面配置文件定义相当于执行了如下shell命令:


mkdir /mnt/cgroups/cpu
mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/cpu
mkdir /mnt/cgroups/cpu/daemons
mkdir /mnt/cgroups/cpu/daemons/www
chown root:root /mnt/cgroups/cpu/daemons/www/*
chown root:webmaster /mnt/cgroups/cpu/daemons/www/tasks
echo 1000 > /mnt/cgroups/cpu/daemons/www/cpu.shares
mkdir /mnt/cgroups/cpu/daemons/ftp
chown root:root /mnt/cgroups/cpu/daemons/ftp/*
chown root:ftpmaster /mnt/cgroups/cpu/daemons/ftp/tasks
echo 500 > /mnt/cgroups/cpu/daemons/ftp/cpu.shares

3.具体演示

#每个子系统下面的配置文件是用来控制相应的资源使用。

3.1控制进程使用cpu资源

跑脚本消耗cpu

x=0
while [ True ];do
    x=$x+1
done;

#top查看cpu使用率,可以看到基本上百分百了。http://www.cndba.cn/Expect-le/article/298http://www.cndba.cn/Expect-le/article/298

[root@node3 ~]# top
Cpu(s): 24.8%us,  0.1%sy,  0.0%ni, 75.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                              
29676 root      20   0  106m 2240 1532 R 100.0  0.0   0:23.67 bash

#下面用cgroup控制这个进程使用的cpu资源

mkdir -p /cgroup/cpu/foo/   #新建一个控制组foo
echo 50000 > /cgroup/cpu/foo/cpu.cfs_quota_us

#将cpu.cfs_quota_us设为50000,相对于cpu.cfs_period_us的100000是50%

echo 29676 > /cgroup/cpu/foo/tasks

--29676是进程pid,添加到控制的任务列表中


#再次查看,cpu使用率为百分之五十了。

[root@node3 ~]# top
Cpu(s): 12.6%us,  0.0%sy,  0.0%ni, 87.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                              
29676 root      20   0  106m 3076 1532 R 49.9  0.0   4:59.09 bash

#cpu控制组foo下面还有其他的控制,还可以做更多其他的关于cpu的控制

[root@node3 ~]# ls /cgroup/cpu/foo/
cgroup.event_control  cgroup.procs  cpu.cfs_period_us  cpu.cfs_quota_us  
cpu.rt_period_us  cpu.rt_runtime_us  cpu.shares  cpu.stat  notify_on_release  tasks

3.2控制进程使用内存资源

耗内存的脚本,内存不断增长

x="a"
while [ True ];do
    x=$x$x
done;


[root@node3 ~]# top
top - 05:30:37 up 2 days,  2:00,  3 users,  load average: 0.40, 0.39, 0.23
Tasks: 189 total,   2 running, 187 sleeping,   0 stopped,   0 zombie
Cpu(s): 12.8%us,  0.2%sy,  0.0%ni, 86.9%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   7940312k total,   927724k used,  7012588k free,    89528k buffers
Swap: 16383996k total,        0k used, 16383996k free,   146444k cached
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND   
29676 root      20   0  617m 225m 1532 R 39.9  4.4   6:02.21 bash   
29676 root      20   0  617m 338m 1532 R 49.9  4.4   6:12.61 bash

#用cgroups控制这个进程的内存资源

mkdir -p /cgroup/memory/foo
echo 1048576 >  /cgroup/memory/foo/memory.limit_in_bytes   
#分配1MB的内存给这个控制组
echo 29676 > /cgroup/memory/foo/tasks     
--29676是进程pid


等一会,脚本就会报错,无法分配脚本所需要的内存,然后被kill掉

[root@node3 ~]# while [ True ];do
> 
>     x=$x$x
> 
> done;
-bash: xrealloc: cannot allocate 18446744071562068096 bytes (323584 bytes allocated)

#被干掉了。

[root@node3 ~]# ps -ef|grep 29676
root      9391  3252  0 05:38 pts/1    00:00:00 grep 29676

 因为这是强硬的限制内存,当进程试图占用的内存超过了cgroups的限制,会触发out of memory,导致进程被kill掉。

  实际情况中对进程的内存使用会有一个预估,然后会给这个进程的限制超配50%比如,除非发生内存泄露等异常情况,才会因为cgroups的限制被kill掉。也可以通过配置关掉cgroups oom kill进程,通过memory.oom_control来实现(oom_kill_disable 1),但是尽管进程不会被直接杀死,但进程也进入了休眠状态,无法继续执行,仍让无法服务。

3.21关于内存的控制,还有以下配置文件

  是关于虚拟内存的控制,以及权值比重式的内存控制等。

3.3控制进程io资源http://www.cndba.cn/Expect-le/article/298

#执行耗io的脚本

dd if=/dev/sda of=/dev/null &

 通过iotop看io占用情况,磁盘速度到了169M/s

10271 be/4 root  169.71 M/s    0.00 B/s  0.00 %  0.00 % dd if=/dev/sda of=/dev/null

下面用cgroups控制这个进程的io资源http://www.cndba.cn/Expect-le/article/298

mkdir -p /cgroup/blkio/foo
echo '8:0   1048576' >  /cgroup/blkio/foo/blkio.throttle.read_bps_device

#8:0对应主设备号和副设备号,可以通过ls -l /dev/sda查看

echo 30252 > /cgroup/blkio/foo/tasks

再通过iotop看,确实将读速度降到了1M/s

10271 be/4 root  1014.36 K/s  0.00 B/s  0.00 %  0.00 % dd if=/dev/sda of=/dev/null

对于io还有很多其他可以控制层面和方式,如下

[root@node3 ~]# ls /cgroup/blkio/foo/
blkio.io_merged         blkio.io_serviced      blkio.reset_stats                
blkio.throttle.io_serviced       blkio.throttle.write_bps_device   blkio.weight          cgroup.procs
blkio.io_queued         blkio.io_service_time  blkio.sectors                    
blkio.throttle.read_bps_device   blkio.throttle.write_iops_device  blkio.weight_device   notify_on_release
blkio.io_service_bytes  blkio.io_wait_time     blkio.throttle.io_service_bytes  
blkio.throttle.read_iops_device  blkio.time                        cgroup.event_control  tasks

  注:进程重启之后(pid会重新分配),需要重新加入到相应的tasks配置文件里才能生效。

cgroup在控制进程使用的资源还是很方便的,也很有效。

版权声明:本文为博主原创文章,未经博主允许不得转载。

cgroup cpu io memory

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
Expect-乐

Expect-乐

关注

Without the continuous bitter cold, there can be no fragrant plum blossom

  • 336
    原创
  • 6
    翻译
  • 100
    转载
  • 41
    评论
  • 访问:1595396次
  • 积分:1957
  • 等级:核心会员
  • 排名:第4名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ