如何使用 CGroup 管理系统资源

http://www.oracle.com/technetwork/cn/articles/servers-storage-admin/resource-controllers-linux-1506602-zhs.html


简介

在大型系统中,内核资源控制器(称为控制组或 cgroup)在帮助战略应用程序获取所需资源且同时限制其他应用程序使用的资源方面可能特别有用。

OTN 旨在帮助您充分熟悉 Oracle 技术以便作出明智的决策。提供文章、软件下载、文档等。立即加入以获取完成工作所需的技术资源。

作为系统管理员,无论您是在大型服务器上整合应用程序还是部署系统以支持云环境中的服务交付,常常需要由您来确保关键负载可以获得它们所需的系统资源。有时,可能需要临时分配资源,例如在会计期末,或者是为了使重要项目能够在严格的截止日期之前如期完成。还有一些其他情况,如应用程序进程很贪婪(声名狼藉的 CPU 或内存消耗大户),有必要限制它们对资源的使用以使其他应用程序不致于得不到资源。

我一直用的是 Oracle Solaris 中的资源控制,因此急于了解在包含 Unbreakable Enterprise Kernel (UEK) 的 Oracle Linux 6 中如何完成同样事情。使用控制组 (cgroup) 进行资源管理只是 Oracle Linux 6 的众多新特性之一。Cgroup 为管理员提供了细粒度的资源分配控制,有助于确保应用程序获得所需资源以提供一致的响应时间和足够的性能。

控制组简介

根据 Linux 内核文档的描述,“控制组提供了一种对任务及其所有未来子任务的集合进行聚合/划分以形成具有特别行为的分层组的机制。”此“行为”由分配系统资源、跟踪使用情况和施加限制的内核子系统(实际资源控制器)定义。分配给每个组的进程将受所定义的资源控制参数集的控制。管理员为每个组分配特定的进程或系统服务,并根据需要调整进程组的资源参数。

在实践中,管理员可以使用 cgroup:

  • 隔离资源消耗往往较大的进程集,限制资源使用不高于预先配置的限制
  • 为一个或一组应用程序分配足够的内存或处理资源(按特定节点或相对份额)
  • 分配网络或存储带宽(I/O 限制)
  • 跟踪已分配的资源
  • 将设备访问限制为特定用户或组(设备白名单)

注意,有些功能(尤其是 I/O 限制)需要 Oracle Linux 6 UEK 第 2 版内核 (2.6.39) 或者 Oracle Linux 6.1 或更高版本中的 Red Hat 兼容内核。可从 ULN 或从公共 yum 服务器获得 UEK 第 2 版内核 Beta 版。

UEK 第 2 版 Beta 内核包括 Linux 容器 (lxc),Linux 容器可提供带有自己的进程和网络空间的隔离环境。我将来可能会在另一篇文章中讨论使用 cgroup 和 Linux 容器的主题,在此重点讨论 Oracle Linux 6 中现在提供的基本 cgroup 功能。对于本文中的示例,我将使用 UEK 第 2 版 Beta 版作为起点。务请阅读资源管理指南以及本文末尾提到的其他参考资源以了解有关 cgroup 的更多信息。

应用控制组

在大型服务器上整合多个负载时,cgroup 显得尤其重要,因为您可以用它在不同的负载之间分配资源。例如,假设我想配置 AMP 栈使得 MySQL 服务器进程总共获得两倍于 Apache Web 服务器进程的 CPU 资源。为使用 cgroup 达到此目的,我为一个 cgroup 分配 2 倍的相对处理能力份额,并将所有 mysqld 进程分配到该组,同时为包含 httpd 进程的组只分配一份相对份额(图 1)。

可向不同进程组分配 CPU 资源相对份额

图 1. 可向不同进程组分配 CPU 资源相对份额。

另一种方法,我可以为每个 cgroup 分配特定的 CPU 和内存资源集,如示意图 2 所示。因为 cgroup 可以控制多种资源,所以我可以向同一 cgroup 分配 CPU 和内存并将该 cgroup 与一组给定的进程关联。

可将特定资源分配给 cgroup 进而分配给进程组

图 2. 可以向 cgroup 分配特定资源并将其指定给进程组。

NUMA 固定

对于 NUMA 架构,通过分配特定资源这种方法,可以让进程总是使用固定不变的处理器和内存节点。这可以让处理器访问本地内存而不是非本地内存,因而可以大幅提高性能。

假设我有一个 NUMA 系统,该系统包括两个节点(为简单起见),如下所示:

# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 4 8 12 16 20 24 28
node 0 size: 32349 MB
node 0 free: 22057 MB
node 1 cpus: 1 5 9 13 17 21 25 29
node 1 size: 32822 MB
node 1 free: 26766 MB
.
.
.

如图 3 所示,我可以将多个处理器核心分到不同的组中并分配给 AMP 栈的特定进程。这里将处理器核心 0、2、4、6、8、10、12 和 14 分配给 group1-web 以支持一组 Apache httpd 后台程序。将处理器核心 1、3、5、7、9、11、13 和 15 分配给 group2-db 以及关联的mysqld 后台程序。将本地内存节点分别分配给各 cgroup。

可以配置 cgroup 以对应 NUMA 节点

图 3. 可以配置 cgroup 以对应 NUMA 节点。

一探究竟

Cgroup 使用基于文件系统的模型来实现 — 正如您可以遍历 /proc 树来查看与进程有关的信息,您可以查看 /cgroup 的层次结构来检查当前控制组层次结构、参数分配和关联任务。

在这个树形文件系统层次结构中,子级继承其父级的属性。该文件系统实现还实现了访问控制 — 每个 cgroup 伪目录有一个所有者和一个组,用来限制哪些人可以修改层次结构及其基础文件,以及哪些进程可以分配给某个 cgroup。

在我举例说明如何配置 cgroup 之前,首先澄清几个术语:

  • cgroup 将一组进程或任务与一个或多个子系统的一组参数关联。
  • 子系统 是一个资源控制器,它对一组进程应用限制或进行操作。每个子系统有实现资源控制和报告机制的特定参数。
  • 层次结构 是一组排列成树形的子系统和 cgroup,使得每个系统进程正好在层次结构中的一个 cgroup 中。

您可以使用 lssubsys 命令(包括在 libcgroup 程序包中)查看可用内核子系统:

# lssubsys -am 
cpuset
cpu
cpuacct
memory
devices
freezer
net_cls
blkio

与 Oracle Linux 6 的最初版本 (2.6.32) 相比,UEK 第 2 版添加了 blkio 子系统以实现 I/O 限制。以下是对各种子系统的简要说明(有关每个子系统及其参数的详细信息,请参见资源管理指南):

  • cpuset 为 cgroup 任务分配各个 CPU 和内存节点
  • cpu 调度 CPU 访问(例如,根据相对份额,如图 1 所示,或针对实时进程)
  • cpuacct 报告所用的总 CPU 时间。
  • memory 报告或限制内存使用。
  • devices 授予或拒绝对设备的访问权限。
  • freezer 挂起或恢复任务。
  • net_cls 使用标识符标记传出网络数据包。
  • blkio 报告或控制块设备的 I/O 带宽。

对于本文中的示例,我将展示如何使用 shell 命令配置非持久性分配,稍后展示如何将这些设置捕获为持久格式。要注意的是(这也是常识!),使用一种技术(如 cgroup)进行可影响内核的修改时,建议您在对生产负载应用更改之前,只在非生产系统上进行动态更改。

我将演示三个示例:

  • 使用 cpuset 子系统实现 NUMA 固定
  • 设备白名单
  • I/O 限制

示例 1:NUMA 固定

为演示如何向一组进程分配 CPU 和内存资源,我将继续假想的 AMP 栈的例子。假设我有一台搭载两个 8 核处理器的物理服务器,我想将 8 个核分配给 Apache Web 服务器,将另外 8 个核分配给 MySQL 数据库,每组都使用一个专用本地内存节点(如图 3 所示)。下面的步骤说明如何对 httpd 和 mysqld 服务器进程进行这些分配。

第 1 步:确认已安装 libcgroup

使用 yum list 命令验证在 Oracle Linux 6 上已安装 libcgroup 程序包:

# yum list libcgroup
Loaded plugins: refresh-packagekit
Installed Packages
libcgroup.x86_64 0.37-2.el6 @anaconda-OracleLinuxServer-201105261616.x86_64/6.1

如果未安装 libcgroup 程序包,请使用命令 yum install libcgroup 安装。

第 2 步:创建 cgroup 层次结构并附加子系统。

有两种办法可以创建层次结构。第一种方法是,首先为层次结构创建一个挂载点,然后使用 mount 命令附加适当的子系统;第二种方法是,使用 cgconfig 服务。在第一种方法中,我使用以下命令创建一个名为 cpu-n-ram 的层次结构并附加 cpucpuset 和 memory 子系统:

# mkdir /cgroup/cpu-n-ram
# mount -t cgroup -o cpu,cpuset,memory - /cgroup/cpu-n-ram

创建 cgroup 层次结构的第二种方法是让 cgconfig 服务读取配置文件 /etc/cgconfig.conf。此文件中该挂载的对等项如下所示:

mount {
   cpuset  = /cgroup/cpu-n-ram;
   cpu     = /cgroup/cpu-n-ram;
   memory  = /cgroup/cpu-n-ram;
}

重新启动 cgconfig 服务将读取该配置文件并创建 /cgroup/cpu-n-ram 层次结构:

# service cgconfig restart 

对于这两种方法,可以使用以下命令确认挂载是否成功:

# mount | grep cgroup
cpu-n-ram on /cgroup/cpu-n-ram type cgroup (rw,cpu,cpuset,memory)

挂载的结果是,使用指定子系统的参数项填充了该层次结构,如清单 1 所示。

清单 1. 使用参数项填充层次结构
# ls /cgroup/cpu-n-ram
cgroup.procs                     memory.failcnt
cpu.rt_period_us                 memory.force_empty
cpu.rt_runtime_us                memory.limit_in_bytes
cpuset.cpu_exclusive             memory.max_usage_in_bytes
cpuset.cpus                      memory.memsw.failcnt
cpuset.mem_exclusive             memory.memsw.limit_in_bytes
cpuset.mem_hardwall              memory.memsw.max_usage_in_bytes
cpuset.memory_migrate            memory.memsw.usage_in_bytes
cpuset.memory_pressure           memory.soft_limit_in_bytes
cpuset.memory_pressure_enabled   memory.stat
cpuset.memory_spread_page        memory.swappiness
cpuset.memory_spread_slab        memory.usage_in_bytes
cpuset.mems                      memory.use_hierarchy
cpuset.sched_load_balance        notify_on_release
cpuset.sched_relax_domain_level  release_agent
cpu.shares                       tasks

子系统参数是 cgroup 资源控制的核心 — 它们本质上来说就像是旋钮,通过旋转这些旋钮,您可以为每个子系统设置限制、限制访问或定义分配。了解具体参数将有助于您了解使用 cgroup 控制资源的种种可能性。tasks 文件(清单 1 输出中的最后一行)跟踪由参数设置控制的层次结构所关联的进程。一旦设置完成(在下面的第 5 步之后),tasks 文件将包含为 cgroup 分配的所有进程 ID (PID)。

第 3 步:创建 cgroup (cgcreate)。

以下 cgcreate 命令将创建名为 group1-web 和 group2-db 的 cgroup:

# cgcreate -g cpuset:/group1-web
# cgcreate -g cpuset:/group2-db

注意,您可以使用用户和组所有权控制哪些人有权在该层次结构中创建 cgroup。相应语法如下,其中 -t <uid:gid> 指定允许向 cgroup 分配任务的用户和组 ID,-a <uid:gid> 指定允许管理 cgroup 和更改子系统参数的用户和组 ID:

cgcreate -t <uid:gid> -a <uid:gid> -g <subsystems:cgroup-path>

自主访问控制 (DAC) 机制应用于代表 cgroup 和子系统参数的目录和文件,从而对 cgroup 更改进行限制,只允许授权用户和组进行 cgroup 更改。

第 4 步:设置 cgroup 的子系统参数 (cgset)。

以下 cgset 命令设置 group1-web 和 group2-db cgroup 的参数,即分配 CPU 和内存节点:

# cgset -r cpuset.cpus='0,2,4,6,8,10,12,14' group1-web
# cgset -r cpuset.cpus='1,3,5,7,9,11,13,15' group2-db
# cgset -r cpuset.mems='0' group1-web
# cgset -r cpuset.mems='1' group2-db

重要提示:如果您在 cgroup 定义中使用 cpuset 子系统,则参数 cpuset.cpus 和 cpuset.mems 是必需的参数,必须对它们进行定义。资源管理指南中记载了所有内核子系统参数。

第 5 步:为 cgroup 分配进程。

有几种办法可以为 cgroup 分配一个或一组进程,以便由关联资源控制来管理这些进程。cgclassify 命令将一个现有进程移到 cgroup 中:

# cgclassify -g cpuset:group1-web 1683

这与在 tasks 文件中放入 PID 1683 有着同样的效果:

# echo 1683 > /cgroup/cpu-n-ram/group1-web/tasks

一个进程的子进程将继承其父进程的 cgroup,因此可以使用“基础”进程以便后续子进程(分解、执行或克隆的)具有与父进程相同的 cgroup。下面用一个简单的办法来说明这一概念,将当前 shell 附加到 cgroup,如下所示:

# echo $$ > /cgroup/cgroup-name/tasks

该 shell 中后续启动的任何进程将自动分配到该 shell 的 cgroup。

或者,还可以使用 cgexec 命令在指定 cgroup 中启动一个进程:

# cgexec -g cpuset:group1-web httpd


对于 /etc/sysconfig 中有配置文件的服务,可以编辑该配置文件以将该服务自动分配到 cgroup。例如,在 /etc/sysconfig/httpd 中添加下面这行代码:

CGROUP_DAEMON="cpuset:group1-web"

然后启动该服务以自动在指定 cgroup 中执行相应进程:

# service httpd start


我们还可以通过设置规则来让 cgred(cgroup 规则引擎后台程序)自动将进程分配给特定组。cgred 后台程序根据 /etc/cgrules.conf文件中的设置将任务移到 cgroup 中。有关详细信息,请参见文档

一旦将进程分配到 cgroup,内核将在设置的资源分配内执行这些任务。在 AMP 进程的示例中,我未给 httpd 和 mysqld 进程指定访问其各自 CPU 和内存资源的独占权限。如果其他进程需要这些资源且 CPU/内存节点可用,它们仍可使用这些已分配的资源来运行。但还有两个参数(cpuset.cpu_exclusive 和 cpuset.mem_exclusive)可以更改此默认行为并授予独占访问权限。

代替 cpuset 子系统的是,我可以使用其他子系统限制 httpd 和 mysqld 进程的 CPU 和内存使用。例如,如果我想让 mysqld 进程组 (group2-db) 合计拥有两倍于 httpd 进程 cgroup (group1-web) 的总 CPU 时间,我可以为 cgroup1-web 设置 cpu.shares=1,并为cgroup2-db 设置 cpu.shares=2,这样就可以为数据库服务器提供两倍的相对 CPU 时间。我还可以使用 memory 子系统参数为 cgroup 设置内存限制。参数 memory.limit_in_bytes 限制 cgroup 中进程的最大用户内存量,而 memory.memsw.limit_in_bytes 同时限制用户内存和交换空间。

示例 2:设备白名单

devices 子系统提供细粒度的系统设备控制。管理员可以定义对特定设备的访问进行限制的 cgroup,并定义哪些用户或组可以访问这些设备,从而增强安全性和数据保护。我将逐步介绍一个示例。

第 1 步:创建 cgroup 并附加子系统。

首先我将创建一个层次结构并附加 devices 子系统:

# mkdir /cgroup/devtest
# mount -t cgroup -o devices - /cgroup/devtest

这将在层次结构中填充代表子系统参数的伪文件:

# ls -l /cgroup/devtest
total 0
-rw-r--r--. 1 root root 0 Jan 16 09:45 cgroup.clone_children
--w--w--w-. 1 root root 0 Jan 16 09:45 cgroup.event_control
-rw-r--r--. 1 root root 0 Jan 16 09:45 cgroup.procs
--w-------. 1 root root 0 Jan 16 09:45 devices.allow
--w-------. 1 root root 0 Jan 16 09:45 devices.deny
-r--r--r--. 1 root root 0 Jan 16 09:45 devices.list
-rw-r--r--. 1 root root 0 Jan 16 09:45 notify_on_release
-rw-r--r--. 1 root root 0 Jan 16 09:45 release_agent
-rw-r--r--. 1 root root 0 Jan 16 09:45 tasks

第 2 步:创建 cgroup (cgcreate)。

以下 cgcreate 命令创建 group3-dev cgroup:

# cgcreate -g devices:/group3-dev

第 3 步:设置子系统参数 (cgset)。

对于本例,我将控制对首个硬盘驱动器 /dev/sda 的访问。为确定 /dev/sda 的主次设备号,我查看设备节点:

# ls -l /dev/sda

brw-rw---- 1 root disk 8, 0 Jan 16 09:24 /dev/sda

根据 ls 的输出结果,/dev/sda 的主设备号为 8,次设备号为 0。以下 cgset 命令设置拒绝对 /dev/sda 进行访问的参数:

# cgset -r devices.deny='b 8:0 mrw' group3-dev


b 指示块设备,但我也可以同时限制对块设备和字符设备的访问。块设备(如硬盘、闪存驱动器和 CDROM)以缓冲块方式移动数据,不同于逐字符传输数据的字符设备(如键盘、鼠标和串行设备)。

第 4 步:为 cgroup 分配进程。

我将向 cgroup 附加当前 shell,以便该 shell 及任何后续命令可以自动分配给 cgroup group3-dev 的 tasks 伪文件:

# echo $$ > /cgroup/devtest/group3-dev/tasks

第 5 步:测试设备访问。

此时,我仍可以访问 inode 并查看该设备是否存在:

# file /dev/sda
/dev/sda: block special

但即使我是 root,我也不能从该设备读取数据或意外运行 fdisk

# dd if=/dev/sda bs=512 count=1
dd: opening `/dev/sda': Operation not permitted
# fdisk /dev/sda
Unable to open /dev/sda

为允许访问,我更改了子系统参数 devices.allow

# cgset -r devices.allow='b 8:0 mrw' group3-dev 

现在我可以从该设备读取数据:

# dd if=/dev/sda of=/dev/null bs=512 count=1 
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000514591 seconds, 995 kB/s

devices 子系统旨在限制或允许对设备的访问,以提供一种细粒度的数据保护方式。

示例 3:I/O 限制

devices 子系统控制或拒绝设备访问,而 blkio 子系统限制对指定块设备的 I/O 操作,如下例所示。

对于分配给 blkio 子系统的进程,我们可以通过两种方式控制它们对块设备的 I/O 操作:

  • 通过加权系数。blkio 子系统参数 (blkio.weight) 允许每个 cgroup 拥有相对份额的可用 I/O。加权机制在完全公平队列 I/O 调度器中实现。(有关详细信息,请参见文档。)
  • 通过 I/O 限制。可以使用子系统参数来为块设备设置 I/O 操作数上限。这提供了一种限制分配到 cgroup 的进程的读/写速率的手段。

在本示例中,我将对一些进程配置限制功能,限制硬盘设备 /dev/sda 的 I/O 带宽(字节/秒)。然后我将展示如何为从该设备读取数据的 cgroup 进程设置每秒 I/O 操作数上限。

限制带宽

第 1 步:创建 cgroup 并附加子系统。

首先确保已挂载 blkio 控制器:

# grep blkio /proc/mounts || mkdir /cgroup/blkio ; mount -t cgroup -o blkio none /cgroup/blkio

第 2 步:创建 cgroup (cgcreate)。

然后创建一个名为 io-test 的 cgroup:

# cgcreate -g blkio:/io-test

第 3 步:为 cgroup 分配进程。

我将当前 shell 分配到此 cgroup,以便 blkio 控制器管理在该 shell 内执行的每一条后续命令的 I/O:

# echo $$ > /cgroup/blkio/io-test/tasks

第 4 步:设置子系统参数。

我希望指定一个带宽速率以限制该 cgroup 中的所有进程对驱动器 /dev/sda 的 I/O。首先使用 hdparm -t 检查设备的未设限读取性能:

# hdparm --direct -t /dev/sda

/dev/sda:
 Timing O_DIRECT disk reads: 350 MB in  3.00 seconds = 116.61 MB/sec

为了建立带宽上限,我需要设置子系统参数 blkio.throttle.read_bps_device。其格式为 <major>:<minor> <bytes_per_second>。同样,查看设备节点以获取主设备号和次设备号:

# ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 Jan 16 10:01 /dev/sda


现在对源于此设备的读取操作设置 1 MB/秒(1024x1024 字节)的限制:

# echo "8:0  1048576" > /cgroup/blkio/io-test/blkio.throttle.read_bps_device

或者,也可以使用 cgset 命令:

# cgset -r blkio.throttle.read_bps_device="8:0 1048576" io-test

再次检查读取性能:

# hdparm --direct -t /dev/sda
/dev/sda:
 Timing O_DIRECT disk reads:   4 MB in  4.00 seconds =   1.00 MB/sec

整体吞吐量现在限制为指定的速率。

可以通过将 blkio.throttle.read_bps_device 设置为 0 取消带宽限制:

# echo "8:0  0" > blkio.throttle.read_bps_device

也可以使用以下方法:

# cgset -r blkio.throttle.read_bps_device="8:0 0" io-test


如果重新检查吞吐量,会发现速率已经回到先前的未设限状态:

# hdparm --direct -t /dev/sda
/dev/sda:
 Timing O_DIRECT disk reads: 352 MB in  3.00 seconds = 117.17 MB/sec

可以按类似方式,通过在 blkio.throttle.write_bps_device 文件中写入每秒字节数来配置写入限制。

限制 IOPS

作为对限制整体带宽的替代方法,还可以限制设备的每秒最大 I/O 操作数 (IOPS)。我将使用 iostat 测量设备的未设限 IOPS(iostat 是sysstat 程序包的一部分),并将使用 hdparm 生成一些磁盘负载。

在另一个 shell(如另一个终端窗口)中运行 iostat 命令:

# iostat 1 -d /dev/sda

输出每秒更新一次,汇总该驱动器的 IOPS 数。在“基础”窗口中,运行 hdparm 命令(具体为 hdparm --direct -t /dev/sda)并观察iostat 的每秒事务值 (tps) 如何变化:

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              31.00     15872.00         0.00      15872          0

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda             235.00    120320.00         0.00     120320          0

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda             240.00    122880.00         0.00     122880          0

注意 tps 如何从空闲模式时的 31 跳到 hdparm 运行时的 230 以上。为将设备 /dev/sda 的 IOPS 速率限制为 50,我返回“基础”窗口并设置blkio 子系统参数以限制读取 IOPS:

# echo "8:0 50" > /cgroup/blkio/io-test/blkio.throttle.read_iops_device

再次运行 hdparm 测试并观察 iostat 输出中的受限每秒事务值:

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.00         0.00         0.00          0          0

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              10.00      5120.00         0.00       5120          0

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              50.00     25600.00         0.00      25600          0

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              50.00     25600.00         0.00      25600          0

可以轻松查看 blkio 资源控制器如何执行作业,将最高 IOPS 速率限制为 50。因此,由 hdparm 测量的吞吐量也将下降。

为禁用基于 IOPS 的 I/O 限制,再次将子系统参数的值设置为 0:

# echo "8:0 0" > /cgroup/blkio/io-test/blkio.throttle.read_iops_device


使用 blkio 控制器为您提供了一种灵活的工具来限制进程组的磁盘 I/O 使用,允许您通过明确定义带宽和吞吐量的上限来建立服务级别协议。

捕获参数

到目前为止,我在命令行所作的所有操作在重新启动后都将失效。一旦设置层次结构、附加 cgroup 并按照我需要的方式定义参数,就可以使用 cgsnapshot 捕获现有配置:

# cgsnapshot -s > cgconfig-example.conf


清单 2 显示捕获的配置。

清单 2. cgsnapshot 输出
# Configuration file generated by cgsnapshot
mount {
	cpuset = /cgroup/cpu-n-ram;
	cpu = /cgroup/cpu-n-ram;
	memory = /cgroup/cpu-n-ram;
devices = /cgroup/devtest;
blkio = /cgroup/blkio;
}

group group2-db {
	cpuset {
		cpuset.memory_spread_slab="0";
		cpuset.memory_spread_page="0";
		cpuset.memory_migrate="0";
		cpuset.sched_relax_domain_level="-1";
		cpuset.sched_load_balance="1";
		cpuset.mem_hardwall="0";
		cpuset.mem_exclusive="0";
		cpuset.cpu_exclusive="0";
		cpuset.mems="1";
		cpuset.cpus="1,3,5,7,9,11,13,15";
	}
	cpu {
		cpu.rt_period_us="1000000";
		cpu.rt_runtime_us="0";
	}
	memory {
		memory.memsw.failcnt="0";
		memory.memsw.limit_in_bytes="9223372036854775807";
		memory.memsw.max_usage_in_bytes="0";
		memory.swappiness="60";
		memory.use_hierarchy="0";
		memory.failcnt="0";
		memory.soft_limit_in_bytes="9223372036854775807";
		memory.limit_in_bytes="9223372036854775807";
		memory.max_usage_in_bytes="0";
	}
}

group group1-web {
	cpuset {
		cpuset.memory_spread_slab="0";
		cpuset.memory_spread_page="0";
		cpuset.memory_migrate="0";
		cpuset.sched_relax_domain_level="-1";
		cpuset.sched_load_balance="1";
		cpuset.mem_hardwall="0";
		cpuset.mem_exclusive="0";
		cpuset.cpu_exclusive="0";
		cpuset.mems="0";
		cpuset.cpus="0,2,4,6,8,10,12,14";
	}
	cpu {
		cpu.rt_period_us="1000000";
		cpu.rt_runtime_us="0";
	}
	memory {
		memory.memsw.failcnt="0";
		memory.memsw.limit_in_bytes="9223372036854775807";
		memory.memsw.max_usage_in_bytes="7303168";
		memory.swappiness="60";
		memory.use_hierarchy="0";
		memory.failcnt="0";
		memory.soft_limit_in_bytes="9223372036854775807";
		memory.limit_in_bytes="9223372036854775807";
		memory.max_usage_in_bytes="7303168";
	}
}

group group3-dev {
	devices {
		devices.deny="a *:* rwm";
		devices.allow="b 8:0 rwm";
	}
}

group io-test {
	blkio {
		blkio.throttle.write_iops_device="";
		blkio.throttle.read_iops_device="";
		blkio.throttle.write_bps_device="";
		blkio.throttle.read_bps_device="";
		blkio.reset_stats="";
		blkio.weight="500";
		blkio.weight_device="";
	}
}


Cgroup 作为服务来实现,它在引导时读取配置文件 /etc/cgconfig.conf 以填充 cgroup 层次结构。为使 cgroup 定义和分配在重新启动后保持有效,可以编辑默认配置文件(插入捕获的子系统挂载、cgroup 定义和参数规范,如清单 2 所示),然后重新启动 cgconfig 服务:

# service cgconfig restart 

一旦重新启动 cgconfig 服务,即可将进程分配到定义的 cgroup,或使用 cgred 后台程序根据创建的规则分配进程。

总结

本文只是浅尝辄止地探讨了 cgroup 可能的用途。很容易就可以看出此特性将如何与 Linux 容器集成 — 管理员将能够通过精确控制 CPU、内存和 I/O 资源来创建用户空间操作环境,这十分适用于整合。我期待着未来围绕 cgroup 和 Oracle Linux 6 UEK 第 2 版的开发。

资源

以下是本文前面所引用的资源:

下面是其他一些资源:

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值