arthur-zhang / morning-up-up

78 stars 6 forks source link

1201 分享:cgroup 和 cpu #26

Open arthur-zhang opened 3 years ago

IKNOWLJT commented 3 years ago

[TOC]

进程间的资源隔离

1. cgroup 简介:

cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制,开发者可以通过cgroups 提供的精细化控制能力,限制某一个或者某一组进程的资源使用,比如在一个既部署了前端 web 服务,也部署了后端计算模块的八核服务器上,可以使用 cgroups 限制 web server 仅可以使用其中的六个核,把剩下的两个核留给后端计算模块。------ 来源:美团技术博客

cgroup是linux内核资源虚拟化的技术基石,LXC(linux Containers)和docker 容器所用到的资源隔离技术就是cgroup。

2. cgroup 概念介绍:

2.1 核心概念
2.2 cgroup 规则:

image-20201201194811465

1、 子系统可以依附于多个层级(当且仅当这些层级没有其他的子系统)如果两个层级同时只有一个cpu子系统是可以的。
2、 一个层级可以附加多个子系统(比如同时附加CPU子系统,内存子系统)
3、 一个任务可以是多个cgroup的成员,但是这些cgroup必须位于不同的层级
4、 子进程自动成为父进程cgroup的成员,可按需求将子进程移到不同的cgroup中

如上图两个任务组成了一个 Task Group,并使用了 CPU 和 Memory 两个子系统的 cgroup,用于控制 CPU 和 MEM 的资源隔离。
cd /sys/fs/cgroup/cpu
sudo mkdir g1
cat cgroup.procs
echo sh -c "pid > cat cgroup.procs"

3. cgroup 使用:

linux cgroup其实就是linux通过虚拟文件系统(VFS)通过文件的方式将cgroups的功能和配置暴露给用户,并将具体的实现细节隐藏起来,给用户态提供一个统一的文件系统API接口。

在我的centos中,在sys/fs 目录下有一个cgroup的目录, 这个目录下有很多的文件目录,例如cpu、memory等等,这些都是cgroup的子系统,每个系统用于不同的资源限制和管理。

image-20201201200028776

如果你想创建一个自己的cgroup,直接在cgroup下的各个目录下创建自己的cgroup,mkdir test_g1创建目录就可以了,删除目录同样使用 rm -rf test_g1就可以了,其中的 cgroup.procs 中的就是该 cgroup 下的进程列表

image-20201201200617689

4. cgroup 实操:

4.1 cpu限制测试
4.1.1 测试代码:还是之前的 fake_make.c
4.1.2 执行程序: ./fake_make -j2, 在没有任何限制的情况下,CPU使用到100%(双核200%)

image-20201201201156513

4.1.3 将刚启动的进程18175 加入到刚创建的cgroup test_g1 下

sudo sh -c "echo 18175 > cgroup.procs"

4.1.4 将CPU的使用率分别限制到20%、80%、100%、150%、200%、250%

限制原理:内核是通过 cpu.cfs_quota_uscpu.cfs_period_us两个参数限制,对于一个周期内cpu.cfs_period_us, 进程实际占用的CPU执行时间不超过cpu.cfs_quota_us

sudo sh -c "echo 20000 > cpu.cfs_quota_us"

通过修改 cpu.cfs_quota_us的值为:20000,80000, 100000, 15000,200000, 250000

分别观察到CPU的使用率:分别是 20%、80%、100%、150%、200%、200%

为防止篇幅过长不截取太多图片,只截取了20000 和 250000

image-20201201203111407

image-20201201203816002

4.1.5 启动两个./fake_make -j2的程序,其中一个不加入任何cgroup,另一个加入一个cgroup,修改加入cgroup的进程的cpu.cfs_quota_us`值, 查看CPU变化情况

通过修改 cpu.cfs_quota_us的值为:20000,80000, 100000, 15000,200000, 250000

分别观察到CPU的使用率:为什么会是这样

加入group的进程: 20%、65%、65%、65%、65%、65%

没有加入group的进程:180%、133%、133%、133%、133%、133%

普通进程是两个线程,但是加入到cgroup的是fakemake进程虽然也是两个线程,但是是一个调度单元,相当于一个调度单元和两个普通线程竞争所以这个普通进程占用的其实是2/3的CPU

4.1.6 启动两个fake_make 的程序,两个加入到同一个cgroup中,修改加入cgroup的进程的cpu.cfs_quota_us值, 查看CPU变化情况

通过修改 cpu.cfs_quota_us的值为:20000,80000, 100000, 15000,200000, 250000

分别观察到CPU的使用率:

加入group的进程: 100%、100%、100%、100%、100%、100%

没有加入group的进程: 100%、100%、100%、100%、100%、100%

4.1.7 启动两个fake_make 的程序,加入到两个不同的cgroup中,修改加入cgroup的进程的cpu.cfs_quota_us值, 查看CPU变化情况

分别观察到CPU的使用率:

cgroup1.cpu.cfs_quota_us 20000 200000 15000 150000 250000

cgroup2.cpu.cfs_quota_us 20000 20000 12000 150000 250000

cgroup1: 20%、 180%、 15%、 100%、 100%

cgroup2: 20%、 20%、 12%、 100%、 100%

4.1.8 在4.1.7 的基础上,在启动一个相同的程序,不加入任何的cgroup,发现

对于

cgroup1.cpu.cfs_quota_us 20000 15000 150000 250000 200000

cgroup2.cpu.cfs_quota_us 20000 12000 150000 250000 20000

cgroup1: 20%、 15%、 50%、 50% 60%、

cgroup2: 20%、 12%、 50%、 50% 20%、

没有cgroup 160%、171%、 100%、 100% 120%、

4.1.5 总结:
wefun94 commented 3 years ago

cgroup 是将进程进行分组化管理的 Linux 内核功能,是一种可以限制单个进程或者多个进程所使用资源的机制。现在很火的docker就使用了cgroup来控制内存和CPU的资源

在/sys/fs/cgroup下的文件夹,对应着cgroup的不同子系统,不同的子系统控制不同的资源管理,例如cpu文件夹下就控制着CPU资源的管理

下面我们来看看cgroup对cpu的资源管理 怎么创建cgroup 在 /sys/fs/cgroup/cpu目录下,创建一个目录,作为group名字 mkdir g1 ,这个目录下会包括进程组的配置文件 echo 13321 > g1/cgroup.procs, 把进程13321加入g1组

在g1目录下有两个配置需要注意,这两个参数用来配置g1组中进程的调度配置 cpu.rt_period_us 进程调度的单位CPU时间 cpu.cfs_quota_us 实时进程在实际占用的CPU时间 这两个值可以控制cgroup占用CPU资源的上限

cgroup下的所有进程会作为一个组,这个组是一个调度资源,和其他普通线程分配CPU资源,而cgroup组下的进程会根据cpu.cfs_period_us和cpu.cfs_quota_us等配置来分配CPU资源

dzy176 commented 3 years ago

第一段"docker 容器所用到的资源隔离技术就是cgroup"是笔误吗?

zqdreamer commented 3 years ago

第一段"docker 容器所用到的资源隔离技术就是cgroup"是笔误吗?

应该没有,是基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离 https://ibb.co/x7F0XjQ

dzy176 commented 3 years ago

第一段"docker 容器所用到的资源隔离技术就是cgroup"是笔误吗?

应该没有,是基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离

资源隔离性是基于namespace, 原文说资源隔离就是用的cgroup, 我以为是笔误, 原来是我理解的片面了. 谢谢comment