CGroup 介绍、应用实例及原理描述【转】
转自:https://www.cnblogs.com/caoxiaojian/p/5633430.html
CGroup 介绍
CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制。2007 年进入 Linux 2.6.24 内核,CGroups 不是全新创造的,它将进程管理从 cpuset 中剥离出来,作者是 Google 的 Paul Menage。CGroups 也是 LXC 为实现虚拟化所使用的资源管理手段。
CGroup 功能及组成
CGroup 是将任意进程进行分组化管理的 Linux 内核功能。CGroup 本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。这些具体的资源管理功能称为 CGroup 子系统或控制器。CGroup 子系统有控制内存的 Memory 控制器、控制进程调度的 CPU 控制器等。运行中的内核可以使用的 Cgroup 子系统由/proc/cgroup 来确认。
CGroup 提供了一个 CGroup 虚拟文件系统,作为进行分组管理和各子系统设置的用户接口。要使用 CGroup,必须挂载 CGroup 文件系统。这时通过挂载选项指定使用哪个子系统。
Cgroups提供了以下功能:
1.限制进程组可以使用的资源数量(Resource limiting )。比如:memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)。
2.进程组的优先级控制(Prioritization )。比如:可以使用cpu子系统为某个进程组分配特定cpu share。
3.记录进程组使用的资源数量(Accounting )。比如:可以使用cpuacct子系统记录某个进程组使用的cpu时间
4.进程组隔离(Isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。
5.进程组控制(Control)。比如:使用freezer子系统可以将进程组挂起和恢复。
CGroup 支持的文件种类
表 1. 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 |
监视状态变化和分组删除事件的配置文件 |
CGroup 相关概念解释
任务(task)。在 cgroups 中,任务就是系统的一个进程;
控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用 cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制;
层级(hierarchy)。控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性;
子系统(subsystem)。一个子系统就是一个资源控制器,比如 cpu 子系统就是控制 cpu 时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。
相互关系
每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup,此 cgroup 在创建层级时自动创建,后面在该层级中创建的 cgroup 都是此 cgroup 的后代)的初始成员;
一个子系统最多只能附加到一个层级;
一个层级可以附加多个子系统;
一个任务可以是多个 cgroup 的成员,但是这些 cgroup 必须在不同的层级;
系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务的 cgroup。
图 1. CGroup 层级图
图 1 所示的 CGroup 层级关系显示,CPU 和 Memory 两个子系统有自己独立的层级系统,而又通过 Task Group 取得关联关系。
CGroup 特点
在 cgroups 中,任务就是系统的一个进程。
控制族群(control group)。控制族群就是一组按照某种标准划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用 cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制。
层级(hierarchy)。控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。
子系统(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 中生成的数据包。
CGroup 应用架构
图 2. CGroup 典型应用架构图
如图 2 所示,CGroup 技术可以被用来在操作系统底层限制物理资源,起到 Container 的作用。图中每一个 JVM 进程对应一个 Container Cgroup 层级,通过 CGroup 提供的各类子系统,可以对每一个 JVM 进程对应的线程级别进行物理限制,这些限制包括 CPU、内存等等许多种类的资源。下一部分会具体对应用程序进行 CPU 资源隔离进行演示。
cgroup的安装
其实安装很简单,最佳实践就是yum直接安装(centos下)
配置文件
/etc/cgconfig.conf
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;
}
cgroup section的语法格式如下
- group <name> {
- [<permissions>]
- <controller> {
- <param name> = <param value>;
- …
- }
- …}
name: 指定cgroup的名称
permissions:可选项,指定cgroup对应的挂载点文件系统的权限,root用户拥有所有权限。
controller:子系统的名称
param name 和 param value:子系统的属性及其属性值
7.1 配置对mysql实例的资源限制
7.1.1 修改cgconfig.conf文件
- mount {
- cpuset = /cgroup/cpuset;
- cpu = /cgroup/cpu;
- cpuacct = /cgroup/cpuacct;
- memory = /cgroup/memory;
- blkio = /cgroup/blkio;
- }
- group mysql_g1 {
- cpu {
- cpu.cfs_quota_us = 50000;
- cpu.cfs_period_us = 100000;
- }
- cpuset {
- cpuset.cpus = "3";
- cpuset.mems = "0";
- }
- cpuacct{
- }
- memory {
- memory.limit_in_bytes=104857600;
- memory.swappiness=0;
- # memory.max_usage_in_bytes=104857600;
- # memory.oom_control=0;
- }
- blkio {
- blkio.throttle.read_bps_device="8:0 524288";
- blkio.throttle.write_bps_device="8:0 524288";
- }
- }
7.1.2 配置文件的部分解释。
cpu:cpu使用时间限额。
cpu.cfs_period_us和cpu.cfs_quota_us来限制该组中的所有进程在单位时间里可以使用的cpu时间。这里的cfs是完全公平调度器的缩写。cpu.cfs_period_us就是时间周期(微秒),默认为100000,即百毫秒。cpu.cfs_quota_us就是在这期间内可使用的cpu时间(微秒),默认-1,即无限制。(cfs_quota_us是cfs_period_us的两倍即可限定在双核上完全使用)。
cpuset:cpu绑定
我们限制该组只能在0一共1个超线程上运行。cpuset.mems是用来设置内存节点的。
本例限制使用超线程0上的第四个cpu线程。
其实cgconfig也就是帮你把配置文件中的配置整理到/cgroup/cpuset这个目录里面,比如你需要动态设置mysql_group1/ cpuset.cpus的CPU超线程号,可以采用如下的办法。
- [root@localhost ~]# echo "0" > mysql_group1/ cpuset.cpus
cpuacct:cpu资源报告
memory:内存限制
内存限制我们主要限制了MySQL可以使用的内存最大大小memory.limit_in_bytes=256M。而设置swappiness为0是为了让操作系统不会将MySQL的内存匿名页交换出去。
blkio:BLOCK IO限额
blkio.throttle.read_bps_device="8:0 524288"; #每秒读数据上限
blkio.throttle.write_bps_device="8:0 524288"; #每秒写数据上限
其中8:0对应主设备号和副设备号,可以通过ls -l /dev/sda查看
- [root@localhost /]# ls -l /dev/sda
- brw-rw----. 1 root disk 8, 0 Sep 15 04:19 /dev/sda
7.1.3 拓展知识
现在较新的服务器CPU都是numa结构<非一致内存访问结构(NUMA:Non-Uniform Memory Access)>,使用numactl --hardware可以看到numa各个节点的CPU超线程号,以及对应的节点号。
本例结果如下:
- [root@localhost /]# numactl --hardware
- available: 1 nodes (0)
- node 0 cpus: 0 1 2 3
- node 0 size: 1023 MB
- node 0 free: 68 MB
- node distances:
- node 0
- 0: 10
以下是较高端服务器的numa信息,仅作参考。
- [root@localhost ~]# numactl --hardware
- available: 4 nodes (0-3)
- node 0 cpus: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60
- node 0 size: 16338 MB
- node 0 free: 391 MB
- node 1 cpus: 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61
- node 1 size: 16384 MB
- node 1 free: 133 MB
- node 2 cpus: 2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62
- node 2 size: 16384 MB
- node 2 free: 137 MB
- node 3 cpus: 3 7 11 15 19 23 27 31 35 39 43 47 51 55 59 63
- node 3 size: 16384 MB
- node 3 free: 186 MB
- node distances:
- node 0 1 2 3
- 0: 10 20 30 20
- 1: 20 10 20 30
- 2: 30 20 10 20
- 3: 20 30 20 10
7.1.4 修改cgrules.conf文件
- [root@localhost ~]# vi /etc/cgrules.conf
- # /etc/cgrules.conf
- #The format of this file is described in cgrules.conf(5)
- #manual page.
- #
- # Example:
- #<user> <controllers> <destination>
- #@student cpu,memory usergroup/student/
- #peter cpu test1/
- #% memory test2/
- *:/usr/local/mysql/bin/mysqld * mysql_g1
注:共分为3个部分,分别为需要限制的实例,限制的内容(如cpu,memory),挂载目标。
7.2 使配置生效
- [root@localhost ~]# /etc/init.d/cgconfig restart
- Stopping cgconfig service: [ OK ]
- Starting cgconfig service: [ OK ]
- [root@localhost ~]# /etc/init.d/cgred restart
- Stopping CGroup Rules Engine Daemon... [ OK ]
- Starting CGroup Rules Engine Daemon: [ OK ]
注:重启顺序为cgconfig -> cgred ,更改配置文件后两个服务需要重启,且顺序不能错。
7.3 启动MySQL,查看MySQL是否处于cgroup的限制中
- [root@localhost ~]# ps -eo pid,cgroup,cmd | grep -i mysqld
- 29871 blkio:/;net_cls:/;freezer:/;devices:/;memory:/;cpuacct:/;cpu:/;cpuset:/ /bin/sh ./bin/mysqld_safe --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
- 30219 blkio:/;net_cls:/;freezer:/;devices:/;memory:/;cpuacct:/;cpu:/;cpuset:/mysql_g1 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --plugin-dir=/usr/local/mysql//lib/plugin --user=mysql --log-error=/usr/local/mysql/data//localhost.localdomain.err --pid-file=/usr/local/mysql/data//localhost.localdomain.pid --socket=/tmp/mysql.sock --port=3306
- 30311 blkio:/;net_cls:/;freezer:/;devices:/;memory:/;cpuacct:/;cpu:/;cpuset:/ grep -i mysqld
7.4 资源限制验证
使用mysqlslap对mysql进行压力测试,看mysql使用资源是否超过限制。
7.4.1 在shell窗口1用mysqlslap对mysql进行压力测试。
- [root@localhost /]# /usr/local/mysql/bin/mysqlslap --defaults-file=/etc/my.cnf --concurrency=150 --iterations=1 --number-int-cols=8 --auto-generate-sql --auto-generate-sql-load-type=mixed --engine=innodb --number-of-queries=100000 -ujesse -pjesse --number-char-cols=35 --auto-generate-sql-add-autoincrement --debug-info -P3306 -h127.0.0.1
7.4.2 在shell窗口2查看mysql对cpu,内存的使用
可见:cpu限制在了第四个核心上,且对第四个核心的使用限制在50%。
7.4.3 在shell窗口3查看io的消耗
可见:mysql对io的读及写消耗均限制在2M每秒以内。
8 cgroup实例分析(手工动态验证)
还原配置文件/etc/cgconfig.conf及/etc/cgrules.conf 为默认配置。测试实例依然为mysql,测试工具为mysqlslap。
开启cgconfig及cgrules 服务。
- [root@localhost /]# /etc/init.d/cgconfig restart
- Stopping cgconfig service: [ OK ]
- Starting cgconfig service: [ OK ]
- [root@localhost /]# /etc/init.d/cgred restart
- Stopping CGroup Rules Engine Daemon... [ OK ]
- Starting CGroup Rules Engine Daemon: [ OK ]
开启mysqlslap压力测试程序。
- [root@localhost /]# /usr/local/mysql/bin/mysqlslap --defaults-file=/etc/my.cnf --concurrency=150 --iterations=1 --number-int-cols=8 --auto-generate-sql --auto-generate-sql-load-type=mixed --engine=innodb --number-of-queries=100000 -ujesse -pjesse --number-char-cols=35 --auto-generate-sql-add-autoincrement --debug-info -P3306 -h127.0.0.1
通过htop查看资源消耗。
8.1 cpu限制实例
限制mysql使用一个核,如第2个核,且对该核的使用不超过50%
- [root@localhost /]# mkdir -p /cgroup/cpu/foo/
- [root@localhost /]# mkdir -p /cgroup/cpuset/foo/
- [root@localhost /]# echo 50000 > /cgroup/cpu/foo/cpu.cfs_quota_us
- [root@localhost /]# echo 100000 > /cgroup/cpu/foo/cpu.cfs_period_us
- [root@localhost /]# echo "0" > /cgroup/cpuset/foo/cpuset.mems
- [root@localhost /]# echo "1" > /cgroup/cpuset/foo/cpuset.cpus
- [root@localhost /]# echo 28819 > /cgroup/cpu/foo/tasks
其中:28819为mysqld的进程号。
8.2 内存限制实例
限制mysql使用内存为不超过512M
跑一个消耗内存脚本
- x='a'
- while [ True ];do
- x=$x$x
- done;
内存的消耗在不断增加,对其进行限制,使其使用内存在500M以内
- [root@localhost /]# mkdir -p /cgroup/memory/foo
- [root@localhost /]# echo 524288000 > /cgroup/memory/foo/memory.limit_in_bytes
- [root@localhost /]# echo 44476 > /cgroup/memory/foo/tasks
内存使用得到了有效控制。
8.3 IO限制实例
跑一个消耗IO的测试
- [root@localhost ~]# dd if=/dev/sda of=/dev/null
通过iotop看io占用情况,磁盘读取速度到了50M/s
限制读取速度为10M/S
- [root@localhost ~]# mkdir -p /cgroup/blkio/foo
- [root@localhost ~]# echo '8:0 10485760' > /cgroup/blkio/foo/blkio.throttle.read_bps_device
- [root@localhost ~]# echo 45033 > /cgroup/blkio/foo/tasks
注1:45033为dd的进程号
注2:8:0对应主设备号和副设备号,可以通过ls -l /dev/sda查看
- [root@localhost ~]# ls -l /dev/sda
- brw-rw----. 1 root disk 8, 0 Sep 15 04:19 /dev/sda
9 cgroup小结
使用cgroup临时对进程进行调整,直接通过命令即可,如果要持久化对进程进行控制,即重启后依然有效,需要写进配置文件/etc/cgconfig.conf及/etc/cgrules.conf
****************************************************************************************
原文地址:http://blog.csdn.net/jesseyoung/article/details/39077829
博客主页:http://blog.csdn.net/jesseyoung
CGroup 介绍、应用实例及原理描述【转】的更多相关文章
- CGroup 介绍、应用实例及原理描述
CGroup 介绍 CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制.记录.隔离进程组 (process groups) 所使用的物力资源 (如 cpu ...
- Json.Net系列教程 1.Json.Net介绍及实例
原文 Json.Net系列教程 1.Json.Net介绍及实例 本系列教程假设读者已经对Json有一定的了解,关于Json在这里不多说.本系列教程希望能对读者开发涉及到Json的.Net项目有一定的帮 ...
- EntityFramework Core上下文实例池原理分析
前言 无论是在我个人博客还是著作中,对于上下文实例池都只是通过大量文字描述来讲解其基本原理,而且也是浅尝辄止,导致我们对其认识仍是一知半解,本文我们摆源码,从源头开始分析.希望通过本文从源码的分析,我 ...
- DNS服务器:主要介绍DNS的服务原理以及安装及其主从配置
DNS服务器:主要介绍DNS的服务原理以及安装及其主从配置 一.DNS简介 1.DNS DNS是域名系统(Domain Name System)的简称,它是一个将域名和IP相互映射的分布式数据库 ...
- Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一)
原文:Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一) 拓展压缩包的使用方式详细介绍 1:将拓展包解压:ThinkPHP3.1.2_Extend.zip --> 将其下的 \ ...
- redis锁机制介绍与实例
转自:https://m.jb51.net/article/154421.htm 今天小编就为大家分享一篇关于redis锁机制介绍与实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要 ...
- Linux守护进程简单介绍和实例具体解释
Linux守护进程简单介绍和实例具体解释 简单介绍 守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程. ...
- Tstrings类简单介绍及实例
用TStrings保存文件;var S: TStrings;begin S := TStringList.Create(); { ... } S.SaveToFile('config.txt' ...
- 从头认识java-15.7 Map(6)-介绍HashMap的工作原理-装载因子与性能
这一章节我们通过讨论装载因子与性能,再来介绍HashMap的工作原理. 1.什么是装载因子?他有什么作用? 以下的代码就是装载因子 /** * The load factor used when no ...
随机推荐
- 剑指Offer_编程题_14
题目描述 输入一个链表,输出该链表中倒数第k个结点. /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : va ...
- hibernate关联关系映射之配置文件
词汇解释 关系:事物之间相互作用.相互联系的状态.范围最大. 联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 关联:表示对象之间的关系,既有数量性,又有方向性:动词:将对象之间 ...
- 设计模式---对象性能模式之享元模式(Flyweight)
一:概念 通过与其他类似对象共享数据来减少内存占用 如果一个应用程序使用了太多的对象, 就会造成很大的存储开销. 特别是对于大量轻量级 (细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字 ...
- golang etcdclientv3使用说明
clientv3.New() 创建连接 config = ec.Config{ Endpoints: []string{"10.0.0.5:2379"}, //连接的etcd集群地 ...
- bzoj千题计划309:bzoj4332: JSOI2012 分零食(分治+FFT)
https://www.lydsy.com/JudgeOnline/problem.php?id=4332 因为如果一位小朋友得不到糖果,那么在她身后的小朋友们也都得不到糖果. 所以设g[i][j] ...
- HDU 1007(套圈 最近点对距离)
题意是求出所给各点中最近点对的距离的一半(背景忽略). 用分治的思想,先根据各点的横坐标进行排序,以中间的点为界,分别求出左边点集的最小距离和右边点集的最小距离,然后开始合并,分别求左右点集中各点与中 ...
- Oracle的 listagg() WITHIN GROUP ()函数使用
1.使用条件查询 查询部门为20的员工列表 -- 查询部门为20的员工列表 SELECT t.DEPTNO,t.ENAME FROM SCOTT.EMP t where t.DEPTNO = ...
- OpenStack配置串口显示虚机界面
OpenStack配置串口显示虚机界面 OpenStack的horizon能够显示虚拟机的界面.horizon是web界面,在我们的电脑上,姑且称之为本地,虚拟机运行在远端服务器上,称之为远端.本地显 ...
- mosh
mosh 是一款使用 UDP 连接 C/S 的终端工具, 服务器只需安装好 mosh 套件, 并启动 SSH 服务, 等待 Client 连接即可. Client (mosh-client) 连接时, ...
- hadoop的基本概念 伪分布式hadoop集群的安装 hdfs mapreduce的演示
hadoop 解决问题: 海量数据存储(HDFS) 海量数据的分析(MapReduce) 资源管理调度(YARN)