0
点赞
收藏
分享

微信扫一扫

Linux Cgroups CPU Subsystem

前言

本文主要会介绍笔者在学习Linux Cgroups CPU Subsystem时所总结的知识点,其中会涉及到Linux CPU进程时间使用、CPU Subsystem的配置参数以及CPU资源监控数据等方面的相关内容。 笔者也会将自己的理解在文中进行阐述,这也算是在和大家交流心得的一个过程。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。

1.CPU时间使用类型

对于CPU这样的计算资源,Linux Cgroups是将进程使用CPU的时长最为基础单位来进行资源限制管控的基本单位的。因此了解Linux中的进程CPU时间使用类型会有助于更好的使用Linux Cgroups CPU Subsystem来管控CPU资源。

如果按照Linux 内的进程状态来分类,则CPU时间使用类型可分为两大类:

  1. 用户态 ni: Nice,即低优先级的用户态进程的CPU使用时长。 us: User,即用户态进程的CPU使用时长,但不包括ni。
  2. 内核态 sys: System, 即内核态进程的CPU使用时长。 id: Idle, 即CPU空闲时间,即无任何进程运行的时长。 wa: IOwait, 即系统等待I/O的CPU使用时长。 hi: Hardware irq, 即处理硬中断的CPU使用时长。 si: Soft irq, 即处理软中断的CPU使用时长。 st: Steal, 即同一宿主机上的vm的CPU使用时长。

2.CPU Subsystem

CPU Subsystem 是Linux Cgroups其中的一个,其负责限制进程对于CPU类资源的使用。

2.1 实现方式

每个Subsystem都是通过一个虚拟文件系统挂载点的方式,挂到一个缺省的目录下。

Tips: 实现原理可以阅读笔者另一遍介绍Linux Cgroups原理的文章

CPU Subsystem一般在 Linux 发行版里会放在 /sys/fs/cgroup/cpu 这个目录下。其次,CPU Subsystem中还会包含多个控制组Control Group;同理,每一个Control Group会在cpu/子目录下建立相应的目录。同时,每一个Control Group还可以包含着其他的Control Group,即Control Group之间的关系是一种树型结构关系。

注意: 这里基于Linux Cgroups V1版本来进行讲解的。

2.2 配置参数

这里介绍几个重要的配置参数。由于Subsystem是绑定在Control Group上,因此每一个Control Group中都会包含如下配置:

参数名 参数说明
cpu.cfs_period_us CFS 算法的一个调度周期(毫秒为单位)
cpu.cfs_quota_us 表示 CFS 算法中,在一个调度周期里这个控制组被允许的运行时间(毫秒为单位)
cpu.shares CPU Cgroup 对于控制组之间的 CPU 分配比例;缺省值为1024
cpu.rt_period_us 设定周期时间。
cpu.rt_runtime_us 设定周期中的运行时间。
cpu.stat 统计信息。其中包含nr_periods(表示经历了几个cfs_period_us周期)、nr_throttled(表示 task 被限制的次数)及throttled_time(表示 task 被限制的总时长)
cgroup.procs 里边记录有属于该组进程的pid
cpuacct.stat 这里包含了两个统计值,这两个值分别是这个控制组里所有进程的内核态 ticks 和用户态的 ticks

2.3 控制策略

CPU 资源控制有两种策略:

  1. 完全公平调度策略(CFS:Completely Fair Scheduler) CFS提供了限额和按比例分配两种方式进行资源控制。CFS算法是Linux中对于普通调度类型进程的调度方法。

  2. 实时调度策略(Real-Time Scheduler) 针对实时进程按周期分配固定的运行时间。配置时间都以微秒(µs)为单位,文件名中用us表示。

2.3.1 CFS

CFS在不同的场景下会有不同的限制管理方法。

2.3.1.1 CPU资源充足情况

一个Control Group被允许使用的CPU最大配额 = 一个调度周期里这个Control Group被允许的运行时间 / 一个调度周期,即: 每个Control Group中所有进程的可使用CPU资源的最大值 = cpu.cfs_quota_us / cpu.cfs_period_us

2.3.1.2 CPU资源消耗殆尽情况

在现实情况中,往往会有多个进程在抢占cpu资源。这些进程都会从属于在不同的Control Group中,此时就会涉及到不同的Control Group之间对于cpu资源的竞争。 而cpu.shares就是为了解决该问题而存在的。通过配置cpu.shares,可以设定每组能够占用cpu资源的比例。 即cpu.shares 这个值决定了CPU Subsystem下Control Group可用 CPU 的相对比例

注意: 只有当系统上CPU资源完全被占满的时候,这个比例才会在各个Control Group间起作用。

实际上设置cpu.shares就是在为进程配置其使用CPU的优先级。即哪个进程的cpu.shares设置的大,它所占有CPU资源的比例就大,因此该进程就有更高的CPU优先使用权。也可以将其理解是在配置进程对于CPU使用的权重大小。

3.CPU资源报告

CPUACCT Subsystem其内部提供了CPU资源用量的统计,时间单位都是纳秒。

Tips: CPUACCT Subsystem可以看作是CPU Subsystem的补充。

其中包括的参数:

  1. cpuacct.usage 统计 cgroup 中所有 task 的 cpu 使用时长。

  2. cpuacct.stat 统计 cgroup 中所有 task 的用户态和内核态分别使用 cpu 的时长。

  3. cpuacct.usage_percpu 统计 cgroup 中所有 task 使用每个 cpu 的时长。

4.CPU绑定

如果某些进程需要在指定的相关CPU上运行,此时可以使用CPUSET Subsystem来实现。CPUSET Subsystem能够为进程分配独立的CPU资源。 其中包括的参数:

  1. cpuset.cpus 在这个文件中填写 cgroup 可使用的 CPU 编号,如0-2,16代表 0、1、2 和 16 这 4 个 CPU。

  2. cpuset.mems 与 CPU 类似,表示 cgroup 可使用的memory node,格式cpuset.cpus。

Tips: 上述两个参数实际上就是Docker实现CPU绑定的实现原理。

举报

相关推荐

0 条评论