奇技指南
Cgroups 的全称是 Control
Groups,它是 Linux 内核提供的一种能够对 cpu,内存等资源实现精细化控制的机制。本文介绍了它的原理以及其在 CephFS
io 限流上的应用。
Cgroups 架构
“Control Groups”的主要功能是将线程及其子线程分为多个组,以便对他们进行分别控制。其具体工作包括:
- 将线程分组
- 为用户提供控制每组线程的操作接口(/sys/fs 文件)
每个 control group 关联一个 cgroup subsystem(controller)。每个 subsystem 用于控制某项特殊的资源(如可以被调度的 cpu 核,内存使用总量等),subsystem 之间可以存在依赖关系。目前 linux 默认会加载的 subsystem 包括:blkio、cpu、cpuacct、cpuset、devices、freezer、hugetlb、memory、net_cls、net_cls,net_prio、net_prio、perf_event、pids、systemd。
如上图所示,在内核中,cgroup 会为每个 /sys/fs/cgroup 下的子目录 (subsystem 对应目录除外) 创建一个 css(cgroup_subsys_state)结构,该结构用于关联该目录对应的 cgroup 结构和所属的 subsystem。每个内核线程的 task 结构中应一个 css_set 域,可以通过获取其中的 css 结构,获得其所属的 control group 信息。
Cgroup 的代码实现大致可分为三部分:
- 在系统启动时(start_kernel), 初始化 cgroup_root,init_css_set(init 线程的 css_set), 各个 subsystem; 将 cgroup_root 挂载至 /sys/fs/cgroup
- 在线程 fork 时, 将父线程的 css_set 赋予子线程, 即:子线程继承父线程的 css_set
- 根据各 subsystem 需求,创建 /sys/fs 下的 subsystem 控制接口文件,用户可以通过向这些文件写入数据实现对某个 control group 的控制,也可通过读取相应文件,获得当前该 control group 的状态。
添加 cgroup subsystem/controller
添加一个子系统需要完成以下工作:
1、实现一组 cgroup 要求 subsystem 实现的 api(如下图所示),其中 css_alloc 和 css_free 是强制要求实现的,其余均可选;css_alloc 用于分配 cgroup_subsys_state 结构所需的内存,用户可在该函数里初始化自己的 subsystem,css_free 用于卸载该 subsystem 时回收相应内存
2、每个子系统拥有一个独立的自定义 name,每个子系统需要定义一个 struct cgroup_subsys 类型的全局变量,该变量名为 <name>_cgrp_subsys;将上面实现的 cgroup subsystem api 赋予该变量相应的域
3、在 inclue/linux/cgroup_subsys.h 里,添加属下 entry:
#if IS_ENABLED(CONFIG_CGROUP_XXX)
SUBSYS(<name>)
#endif
实现 cephfs 客户端 io 限流
Cephfs 客户端限流的目标:限制 cephfs 内核客户端元数据 / 数据操作速率(ops/byte per second)。目前我们采用的限流算法是令牌桶算法。
实现步骤如下:
1、添加 include/linux/cgroup_cephfs.h 头文件,定义 cephfscg 结构,其中包含 cgroup_subsys_state 域;同时定义其他所需类型(如令牌桶限流阀 token_bucket_throttle)
2、实现 cgroup cephfs subsystem
- a)实现 css_alloc 和 css_free 函数
- b)定义 cephfs
subsystem 的接口文件,其中 meta_ops 和 data_ops 用于设置元数据操作和数据操作令牌桶的更新周期,meta_ops.iops 和 data_ops.iops 用于设置元数据 / 数据操作的 iops 限制,data_ops.band 用于设置数据操作的吞吐量限制;除定位文件外,还需要设置这些文件的读写处理函数, 这里所有读写操作均由 cephfscg_set_throttle_params 和 cephfscg_throttle_params_read 完成;
- c)定义 cephfs_cgrp_subsys 变量
- d)在 Include/linux/cgroup_subsys.h 增加相应的 entry
3、在 cephfs 文件操作执行路径上增加相应的控制操作(获取当前 task 的 css 结构,并调用其对应的限流接口)
本文介绍了 cgroups 架构以及添加子系统的方法,并通过 cgroups 在 cephfs 中的应用,进一步展示了 cgroups 精细化控制能力。希望通过整篇文章的介绍,读者能够大致了解 cgroups 的功能。
相关推荐
浅谈 Cgroups
(360 技术原创内容,转载务必注明出处保存文末二维码图片,谢谢配合。)
关注 360 技术,发现更多有料干货~