文章目录
简介
Linux cgroups的全称Linux Control Group。它可以限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等,还可以对进程进行优先级设置、审计,以及将进程挂起和恢复。
举一个例子,如果需要限制进程A、B一共可以使用第一个核的10%,和20%的内存,就可以使用cgroup技术来实现。
cgroup和namespace技术是linux容器技术的基石,cgroup被用来限制资源使用,namespace被用来隔离进行。它们被广泛用于容器化的场景,比如docker,k8s等。
cgroup以文件系统的方式暴露给用户使用,一般以文件和目录的方式组织在操作系统的/sys/fs/cgroup路径下。
cgroup分为不同的子系统,不同的子系统具有不同的功能,如果要某一个进程要使用某个子系统,只需要将进程id添加到对应的子系统的task文件中即可。
子系统
cgroup包括多个子系统
- cpu 子系统:限制cpu的使用
- memory 子系统:限制内存使用
- cpuset 子系统:可以为进程组分配单独的cpu或者内存节点
- cpuacct 子系统:统计cpu group的使用情况
- blkio 子系统:限制IO,一般用于磁盘
- devices 子系统:限制进程使用的设备
- freezer 子系统:可以挂起和恢复进程组
- net_cls 子系统,可以标记进程组的网络数据包,使用 tc 模块(traffic control)对数据包进行控制
以下是阿里云服务器的cgroup目录接口,可以看到阿里云也是使用cgroup技术进行限制资源的,且可以看到不同的子系统对应的目录。
cpu子系统
了解cpu子系统需要进入cpu的目录,上图将cpu和cpuacct挂载到了同一个目录。
上述不同的文件代表着不同的功能。
cpu.cfs_period_us cpu.cfs_quota_us
这两个文件可以一起用来限制CPU的使用,且需要两个文件一起配置。
cpu.cfs_period_us 用来配置时间周期长度,默认100000(100ms),cpu.cfs_quota_us用来配置当前cgroup在时间周期长度内能够使用的CPU时间,默认100,用来限制使用CPU的上限。单位都是微秒(us),从配置上也可以看出这是一个周期长度内的限制,周期越短越精确。
cpu.shares
cpu.shares 可以用来设置相对值,当有多个cpu group时,会根据cpu.shares计算可以得到多少cpu资源。
cpu.stat
cpu.stat和统计相关,统计了进程组使用CPU的情况,包含3个指标。
memory
memory 子系统可以限制和统计进程组对内存资源的使用。该子系统对应的目录结构。
限制内存使用的文件
- memory.limit_in_bytes: 设置进程组可以使用的内存的上限
- memory.memsw.limit_in_bytes: 设置进程组可以使用的内存和可以使用的交换分区的之和的上限
统计内存使用的文件
- memory.usage_in_bytes: 此刻进程组使用的内存的大小
- memory.max_usage_in_bytes: 历史上进程组使用的内存的峰值大小
- memory.memsw.usage_in_bytes: 此刻进程组使用的内存和交换分区之和的大小
- memory.memsw.max_usage_in_bytes:历史上进程组使用内存和交换分区之和的峰值大小
- memory.failcnt :进程组内存使用超过memory.limit_in_bytes而导致的内存分配失败次数
- memory.memsw.failcnt:进程组内存使用超过memory.memsw.limit_in_bytes而导致的内存分配失败次数
- memory.stat :当前进程组的内存使用情况的统计信息
memory.limit_in_bytes memory.memsw.limit_in_bytes
memory.limit_in_bytes 限制进程组使用内存的上限,memory.memsw.limit_in_bytes限制进程组使用内存和交换分区的上限大小。单位是字节(byte)。
memory.failcnt
该参数统计统计进程组内存使用超过memory.limit_in_bytes而导致的内存分配失败的次数,该参数递增。
- 如果该参数保持不变,这说明进程组使用的内存充足
- 如果该参数递增,则说明进程组使用的内存资源不足
cpuset子系统
cpuset子系统可以限制进程组使用的CPU节点和内存节点,这个参数和NUMA(Non Uniform Memory Access)架构相关。NUMA架构是指一个NUMA集成了一系列CPU核和一个内存,一个服务器可以有多个NUMA节点,跨NUMA访问数据比在同一个NUMA内访问数据慢。因此如果对性能非常敏感,尽量避免跨NUMA节点访问。
cpuset.cpus
cpuset.cpus 可以限制进程组使用的CPU节点
cpuset.mems
cpuset.mems 限制可以使用的memory节点
原理
在linux进程的struct内,有一个指针,最终指向了cgroup配置信息。相当于进程给内核提供了一个钩子,在调度的时候可以拿到cgroup信息,并且根据cgroup的信息进行调度。
本篇仅限于简单介绍cgroup cpu memory cpuset子系统的功能、使用和原理,更详细的可以参考 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/ch01