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 文件系统。这时通过挂载选项指定使用哪个子系统。
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)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。
可用的子系统
- blkio — 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。
- cpu — 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
- cpuacct — 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
- cpuset — 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
- devices — 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
- freezer — 这个子系统挂起或者恢复 cgroup 中的任务。
- memory — 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
- net_cls — 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
-
ns — 名称空间子系统。
作为数据库通常比较关注的是,blkio,cpuset,memory三个子系统。
相互关系
- 每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 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)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。
图 2. CGroup 典型应用架构图
如图 2 所示,CGroup 技术可以被用来在操作系统底层限制物理资源,起到 Container 的作用。图中每一个 JVM 进程对应一个 Container Cgroup 层级,通过 CGroup 提供的各类子系统,可以对每一个 JVM 进程对应的线程级别进行物理限制,这些限制包括 CPU、内存等等许多种类的资源。下一部分会具体对应用程序进行 CPU 资源隔离进行演示。
CGroup 部署及配置介绍
安装cgroup
rhel系统使用
yum install libcgroup
cgconfig服务
安装后会生成cgconfig服务,使用
service cgconfig status
–查看服务状态
service cgconfig stop
–停止服务
service cgconfig start
–开启服务
service cgconfig restart
–重启服务
lssubsys -am
–也可以使用这个命令查看子系统的挂载情况
/etc/cgconfig.conf配置文件
cgconfig.conf配置文件有两个区块,一个是mount,一个是group,先来看看mount.
默认的内容如下:
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;
}
代表执行了以下命令:
mkdir /cgroup/cpu
mount -t cgroup -o cpu cpu /cgroup/cpu
....
group的语法如下
group <name> {
[<permissions>]
<controller> {
<param name> = <param value>;
…
}
…
}
permissions部分是可选的,如果你是作为管理员(root)给相关程序授权,可以忽略这个选项。
group mysql_g1 {
perm {
task {
uid = root;
gid = mysql;
} admin {
uid = root;
gid = root;
}
}
cpuset {
cpuset.cpus = "3";
cpuset.mems = "0";
}
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";
}
}
这是一个常用的mysql cgroup配置文件,限制了cpuset,memory和blkip三个子系统。
我们详细看看配置文件.类似执行了如下命令
mkdir -p /cgroup/cpu/mysql_g1
chown root:root /cgroup/cpu/mysql_g1/*
chown root:mysql /cgroup/cpu/mysql_g1/tasks
echo 3 > /cgroup/cpuset/mysql_g1/cpuset.cpus
修改配置文件以后,可以使用
service cgconfig restart
–来使配置生效
将某个或者多个进程加入到某个子系统中。
cgclassify -g cpu,memory:group1 1701
cgclassify 的语法为:cgclassify -g subsystems:path_to_cgroup pidlist,其中:
- subsystems 是用逗号分开的子系统列表,或者 * 启动与所有可用子系统关联的层级中的进程。请注意:如果在多个层级中有同名的 cgroup,则 -g 选项会将该进程移动到每个组群中。请确定在拥有您在此指定子系统的每个层级中都有该 cgroup。
- path_to_cgroup 是到其层级中的 cgroup 的路径
- pidlist 是用空格分开的进程识别符(PID)列表
- 您还可以在 pid 前面添加 –sticky 选项以保证所有子进程位于同一 cgroup 中。如果您没有设定这个选项且 cgred 守护进程正在运行,则会根据 /etc/cgrules.conf 中的设置将子进程分配到 cgroup 中。该进程本身则仍保留在启动它的 cgroup 中。
上面命令类似执行了
echo 1701 > /cgroup/lab1/group1/tasks
cgred守护进程
cgred是一个守护进程,它可根据在 /etc/cgrules.conf 文件中设定的参数将任务移动到 cgroup 中。/etc/cgrules.conf 文件中的条目可以使用以下两个格式之一:
- user hierarchies control_group
-
user:command hierarchies control_group
*:/usr/local/mariamysql/bin/mysqld * mysql_g1
这里的实例代表任何用户启动的mysqld进程,都包含到所有已经挂载的子系统的mysql_g1组中。
查看哪些系统在cgroup中运行
ps -eo pid,cgroup,cmd | grep -i mysqld
查看某个控制组群可以设置哪些参数
cgget -g cpuset /
–cpuset可以替换成其他控制组群名称
cgroup 命令最权威的文档是 libcgroup 软件包提供的手册页。这部分的数字在以下 man page 列表中指定。
libcgroup Man Page
- man 1 cgclassify — cgclassify 命令是用来将运行的任务移动到一个或者多个 cgroup。
- man 1 cgclear — cgclear 命令是用来删除层级中的所有 cgroup。
- man 5 cgconfig.conf — 在 cgconfig.conf 文件中定义 cgroup。
- man 8 cgconfigparser — cgconfigparser 命令解析 cgconfig.conf 文件和并挂载层级。
- man 1 cgcreate — cgcreate 在层级中创建新 cgroup。
- man 1 cgdelete — cgdelete 命令删除指定的 cgroup。
- man 1 cgexec — cgexec 命令在指定的 cgroup 中运行任务。
- man 1 cgget — cgget 命令显示 cgroup 参数。
- man 5 cgred.conf — cgred.conf 是 cgred 服务的配置文件。
- man 5 cgrules.conf — cgrules.conf 包含用来决定何时任务术语某些 cgroup 的规则。
- man 8 cgrulesengd — cgrulesengd 在 cgroup 中发布任务。
- man 1 cgset — cgset 命令为 cgroup 设定参数。
- man 1 lscgroup — lscgroup 命令列出层级中的 cgroup。
- man 1 lssubsys — lssubsys 命令列出包含指定子系统的层级。
查看各子系统可以调节的参数请链接到此地址
网友评论已有0条评论, 我也要评论