cgroups 是 Linux 内核提供的一种资源管理机制,可以用于限制进程组(包括单个进程或一组相关进程)的资源使用。通过创建和配置相应的 cgroup,可以限制程序可使用的内存量。
在Linux环境中,cgroup
(控制组)是一种用来限制、记录和隔离进程组所使用的物理资源(如CPU、内存、磁盘I/O等)的机制。
https://blog.csdn.net/yuelai_217/article/details/131332809
这些是与 CPU 控制组 (cgroup) CPU 资源使用和配置相关的文件和目录。
这些文件和目录提供了对 CPU 控制组的配置和监控。可以使用这些文件来设置 CPU 资源分享、限制 CPU 使用时间、查看 CPU 使用统计信息等。根据实际需求和系统配置,操作这些文件来管理和控制 CPU 资源的分配和使用。
下面是对其中一些文件和目录的解释:
文件名 | 解释 |
---|---|
cpuacct.usage | : 显示 CPU 控制组中所有进程的累计 CPU 使用时间。 |
cpu.shares | : 用于设置 CPU 资源分享权重,值越高表示分配的 CPU 资源越多。 |
cgroup.clone_children | : 控制是否在创建新的控制组时自动克隆父控制组的配置。 |
cpuacct.usage_percpu | : 显示每个 CPU 核心的 CPU 使用时间。 |
cpu.stat | : 提供有关 CPU 使用情况的统计信息,如用户态时间、内核态时间等。 |
cgroup.event_control | : 用于控制和监控 cgroup 的事件。 |
cgroup.procs | : 显示属于该 cgroup 的所有进程的进程 ID。 |
cgroup.sane_behavior | : 控制组的行为设置,用于启用或禁用特定行为。 |
cpuacct.stat | : 提供有关 CPU 使用的统计信息,例如用户态时间、内核态时间等。 |
cpu.cfs_period_us | : 配置 CPU 使用时间片的周期,单位为微秒。 |
cpu.cfs_quota_us | : 配置 CPU 使用时间片的配额,单位为微秒。 |
notify_on_release | : 控制在释放 cgroup 时是否发送通知。 |
release_agent | : 设置释放 cgroup 时要运行的命令或脚本。 |
system.slice | : 默认的系统级控制组。 |
tasks | : 包含属于该 cgroup 的所有进程的进程 ID。 |
/sys/fs/cgroup/memory
是与内存控制组 (cgroup) 相关的文件和目录。它们提供了有关内存资源使用和配置的信息。下面是对其中一些文件和目录的解释:
cgroup.clone_children | 控制是否在创建新的控制组时自动克隆父控制组的配置。 |
---|---|
cgroup.event_control | 用于控制和监控 cgroup 的事件。 |
cgroup.procs | 显示属于该 cgroup 的所有进程的进程 ID。 |
cgroup.sane_behavior | 控制组的行为设置,用于启用或禁用特定行为。 |
memory.failcnt | 发生内存资源超限的次数。 |
memory.force_empty | 强制清空内存控制组中的所有缓存。 |
memory.kmem.failcnt | 发生内核内存资源超限的次数。 |
memory.kmem.limit_in_bytes | 配置内核内存使用的限制,以字节为单位。 |
memory.kmem.max_usage_in_bytes | 内核内存使用的最大值,以字节为单位。 |
memory.kmem.slabinfo | 提供有关内核内存使用的详细信息。 |
memory.kmem.tcp.failcnt | 发生针对 TCP 使用的内核内存超限的次数 |
memory.kmem.tcp.limit_in_bytes | 配置针对 TCP 使用的内核内存的限制,以字节为单位。 |
memory.kmem.tcp.max_usage_in_bytes | 针对 TCP 使用的内核内存的最大值,以字节为单位。 |
memory.kmem.tcp.usage_in_bytes | 针对 TCP 使用的内核内存的当前使用量,以字节为单位。 |
memory.kmem.usage_in_bytes | 内核内存的当前使用量,以字节为单位。 |
memory.limit_in_bytes | 配置内存使用的限制,包括文件缓存和应用程序内存,以字节为单位。 |
memory.max_usage_in_bytes | 内存使用的最大值,包括文件缓存和应用程序内存,以字节为单位。 |
memory.move_charge_at_immigrate | 控制在迁移进程时是否转移内存使用量。 |
memory.numa_stat | 提供有关 NUMA(非一致性存储访问)的内存统计信息。 |
memory.oom_control | 控制内存超限时的 OOM (Out of Memory) 行为。 |
memory.pressure_level | 提供有关内存压力级别的信息。 |
memory.soft_limit_in_bytes | 配置软限制内存使用的限制,以字节为单位。 |
memory.stat | 提供有关内存使用的统计信息,如分配的页面数、缓存页面数等。 |
memory.swappiness | 控制内存页交换的倾向性。 |
memory.usage_in_bytes | 当前内存使用量,包括文件缓存和应用程序内存,以字节为单位。 |
memory.use_hierarchy | 控制是否使用层次结构来跟踪内存使用。 |
notify_on_release | 控制在释放 cgroup 时是否发送通知。 |
release_agent | 设置释放 cgroup 时要运行的命令或脚本。 |
system.slice | 默认的系统级控制组。 |
tasks | 包含属于该 cgroup 的所有进程的进程 ID。 |
cgconfig 是一个用于管理控制组 (cgroup) 的服务。它负责加载和应用控制组的配置文件,并创建、管理和监控相应的控制组层次结构。
当启用 cgconfig 服务时,它会在系统启动时自动加载并读取指定位置的配置文件(例如 /etc/cgconfig.conf 或 /etc/cgconfig.d/ 目录下的配置文件)。这些配置文件定义了控制组的层次结构、资源限制和权限设置等规则。
# 开机启动cgconfig服务
systemctl enable --now cgconfig
vim /etc/cgconfig.d/PostgreSQL.conf
## 定义需要创建的cgroup子系统及其挂载点,这里创建cpu与cpuacct(统计)两个cgroup子系统
mount {
cpu = /mnt/cgroups/cpu;
cpuacct = /mnt/cgroups/cpu;
}
## 定义db_cage(数据库服务器进程)组
group db_cage {
# 用户和组 "postgres" 可以管理这些 cgroup
perm {
task {
# 指定 UID 为 postgres
uid = postgres;
# 指定 GID 为 postgres
gid = postgres;
# 设置文件权限为 774
fperm = 774;
}
admin {
# 指定 UID 为 postgres
uid = postgres;
# 指定 GID 为 postgres
gid = postgres;
# 设置目录权限为 775
dperm = 775;
# 设置文件权限为 774
fperm = 774;
}
}
# 限制内存为 1GB 并禁用交换分区
memory {
# 限制内存使用为 1GB
memory.limit_in_bytes = 1G;
# 限制总内存(包括交换分区)使用为 1GB
memory.memsw.limit_in_bytes = 1G;
}
# 限制设备 8:0 的读取和写入 I/O 速度为每秒 10MB
blkio {
# 限制读取速度为 10MB/s
blkio.throttle.read_bps_device = "8:0 10485760";
# 限制写入速度为 10MB/s
blkio.throttle.write_bps_device = "8:0 10485760";
}
# 将 CPU 时间限制为每秒钟的 0.25 秒
cpu {
# 设置 CPU 周期为 1 秒
cpu.cfs_period_us = 1000000;
# 设置 CPU 配额为 0.25 秒
cpu.cfs_quota_us = 250000;
}
# 只允许使用 CPU 0-3 和内存节点 0
cpuset {
# 指定可使用的 CPU 为 0-3
cpuset.cpus = 0-3;
# 指定可使用的内存节点为 0
cpuset.mems = 0;
}
}
https://developer.aliyun.com/article/43544
## 定义需要创建的cgroup子系统及其挂载点,这里创建cpu与cpuacct(统计)两个cgroup子系统
mount {
cpu = /mnt/cgroups/cpu ;
cpuacct = /mnt/cgroups/cpu ;
}
## 定义daemons/www(web服务器进程)组
group daemons/www {
## 定义这个组的权限
perm {
task {
uid = root ;
gid = webmaster ;
}
admin {
uid = root ;
gid = root ;
}
}
## 定义cpu子系统的属性及CPU资源分享权重值,即属于此组的任务的权重为1000
cpu {
cpu.shares = 1000 ;
}
}
## 定义daemons/ftp(ftp进程)组
group daemons/ftp {
perm {
task {
uid = root ;
gid = ftpmaster ;
}
admin {
uid = root ;
gid = root ;
}
}
## 定义cpu子系统的属性及CPU资源分享权重值,即属于此组的任务的权重为1000为500
cpu {
cpu.shares = 500 ;
}
}
上面配置文件定义
相当于执行了如下shell命令
:
# 创建一个名为 /mnt/cgroups/cpu 的目录,用于挂载 CPU 控制组。
mkdir /mnt/cgroups/cpu
# 将 CPU 控制组挂载到 /mnt/cgroups/cpu 目录,使其可用。
mount -t cgroup -o cpu,cpuacct cpu /mnt/cgroups/cpu
# 在 /mnt/cgroups/cpu 目录下创建一个名为 daemons 的子目录,用于组织 CPU 控制组。
mkdir /mnt/cgroups/cpu/daemons
# 在 /mnt/cgroups/cpu/daemons 目录下创建一个名为 www 的子目录,用于表示名为 www 的进程组。
mkdir /mnt/cgroups/cpu/daemons/www
# 将 /mnt/cgroups/cpu/daemons/www 目录下的所有文件的所有者和所属组设置为 root。
chown root:root /mnt/cgroups/cpu/daemons/www/*
# 将 /mnt/cgroups/cpu/daemons/www/tasks 文件的所有者设置为 root,所属组设置为 webmaster。
chown root:webmaster /mnt/cgroups/cpu/daemons/www/tasks
# 将 /mnt/cgroups/cpu/daemons/www/cpu.shares 文件中的内容设置为 1000,这是用来设置 CPU 资源分享权重的值。
echo 1000 >/mnt/cgroups/cpu/daemons/www/cpu.shares
# 在 /mnt/cgroups/cpu/daemons 目录下创建一个名为 ftp 的子目录,用于表示名为 ftp 的进程组。
mkdir /mnt/cgroups/cpu/daemons/ftp
# 将 /mnt/cgroups/cpu/daemons/ftp 目录下的所有文件的所有者和所属组设置为 root。
chown root:root /mnt/cgroups/cpu/daemons/ftp/*
# 将 /mnt/cgroups/cpu/daemons/ftp/tasks 文件的所有者设置为 root,所属组设置为 ftpmaster。
chown root:ftpmaster /mnt/cgroups/cpu/daemons/ftp/tasks
# 将 /mnt/cgroups/cpu/daemons/ftp/cpu.shares 文件中的内容设置为 500,这是用来设置 CPU 资源分享权重的值。
echo 500 >/mnt/cgroups/cpu/daemons/ftp/cpu.shares
常用的cgroup工具命令:
cgcreate
- 创建cgroupcgdelete
- 删除cgroupcgexec
- 在cgroup中执行命令cgclassify
- 将进程移动到cgroupcgget
- 获取cgroup参数cgset
- 设置cgroup参数请注意,这些方法仅限制程序在用户空间
中使用的内存,而不包括内核
占用的内存。另外,这些方法都需要适当的权限来设置和管理资源限制。确保您具有足够的权限,并了解如何正确应用这些限制。
首先,需要确保系统已安装并配置了 cgroups。然后,可以使用工具如 cgcreate
、cgset
和 cgexec
来创建和管理 cgroups
。
以下是一些示例
:
# 创建 cgroup
cgcreate -g <subsystem>:/<cgroup_name>
# 等同于在cgroup目录下手动创建目录
mkdir /sys/fs/cgroup/<subsystem>/<cgroup_name>
# 创建一个限制内存的cgroup:
cgcreate -g memory:/app1
# 等同于在memory目录下创建app1目录
mkdir -p /sys/fs/cgroup/memory/app1
# 创建一个限制CPU的cgroup:
cgcreate -g cpu:/app1
# 等同于在cpu目录下创建app1目录
mkdir -p /sys/fs/cgroup/cpu/app1
使用app1这个cgroup进程组限制名为 my_app 的程序及其子进程。
# 将进程加入cgroup
cgclassify -g <subsystem>:<cgroup进程组> <pid>
# 将一个进程添加到cgroup:
cgclassify -g cpu:demo pid编号
# 等同于将PID写入到该文件中
echo $$ > /sys/fs/cgroup/cpu/demo/tasks
# 将my_app程序运行在app1这个cgroup 中:
cgexec -g memory:app1 my_app
限制一个进程组的内存使用量为 1GB:
# 设置内存限制为 1GB:
cgset -r memory.limit_in_bytes=1G app1
# 设置cgroup的cpu限制:
## 1000表示该程序只能使用1%的CPU
cgset -r cpu.cfs_quota_us=1000 app1
# 等同于将1000写入该文件
echo 1000 > /sys/fs/cgroup/cpu/app1/cpu.cfs_quota_us
# 查看cgroup的cpu使用情况:
## -r cpu.stat 指定要查询的资源参数为 cpu.stat,即 CPU 统计信息。
cgget -r cpu.stat app1
# 查看cgroup的cpu使用情况:
cat /sys/fs/cgroup/cpu/app1/cpu.stat
# 查看 cgroup 的使用情况
## -g 指定要执行命令的控制组路径
## -l 显示执行命令时的资源限制信息
cgexec -g <cgroup_path> -l
# 删除app1这个cgroup
cgdelete -g memory:/app1
# 等同于删除cgroup的指定目录--不可执行
rmdir /sys/fs/cgroup/<subsystem>/<cgroup_name>