cgclassify 命令详解
更新时间:2026-09-17。本文是「一个命令一个文档」系列,聚焦
cgclassify(control group classify,归类进控制组)——容器与云原生命令族、libcgroup 套件。cgexec 只能管"启动时就入组"的新进程,cgclassify专门把已经在跑的进程事后搬进/搬出控制组。
cgclassify 把一个或多个 PID 写入目标控制组的任务文件,从写入的那一刻起改变它们所属的组及其资源约束,不需要重启进程。常用于线上应急:某个任务突然开始抢资源,临时给它套上限或挪到低优先级组。
一、基本用法
cgclassify -g cpu,memory:lowpri 12345 # 把 PID 12345 移进 lowpri 组
cgclassify -g cpu:lowpri 12345 12346 12347 # 一次移多个 PID
cgclassify --sticky -g cpu:lowpri 12345 # sticky:连子线程也固定在该组
cgclassify -g memory:limited $(pgrep -f worker) # 按进程名批量移动
-g 控制器:组名后直接跟 PID 列表。移动是即时生效的:若目标组内存上限小于进程当前占用,进程会立刻进入内存回收、甚至被 OOM,因此往更小的 memory 组挪进程要先评估用量(用 cgget 看usage_in_bytes)。
二、实战:给失控任务临时降权
# 1) 发现一个编译/压测进程把 CPU 抢满
top
# 2) 建一个低权重 + 硬限的组(若还没有)
cgcreate -g cpu:throttle
cgset -r cpu.shares=128 -r cpu.cfs_quota_us=50000 throttle
# 3) 不杀进程、不重启,直接把它挪进去
cgclassify -g cpu:throttle $(pgrep -f make)
# 4) 验证:看组的 cpuacct.usage 在涨、目标 PID 已在 tasks 里
cgget -g cpuacct:throttle | grep usage
cat /sys/fs/cgroup/cpu/throttle/tasks这类"热迁移"正是 cgclassify 相对 cgexec 不可替代的地方——线上进程不能停,却要立刻限制它。移动后该进程已经申请到的内存不会被立刻压缩,但后续新分配受新组约束,CPU 则在下一个调度周期立即按新 shares/quota 生效。
三、与 cgexec、cgred 的分工
| 工具 | 作用 |
|---|---|
| cgexec | 启动一个新进程并直接入组 |
| cgclassify | 把已存在的 PID 移到组里 |
cgred(cg规则守护) | 按 /etc/cgrules.conf 规则,自动把匹配用户/进程名的任务持续归类 |
| cgget / systemd-cgls | 查看某 PID 当前在哪个组、组里有哪些进程 |
--sticky主要用在有 cgred 自动分类的系统:默认 cgred 可能按规则把你的进程再挪走,加 sticky 后子进程/线程被钉在手工指定的组。查一个进程当前归属:cat /proc/<PID>/cgroup(v1 会列出每个控制器,v2 只有一行0::/路径)。
四、v2 与 systemd 等价做法
cgroup v2 没有 cgclassify,直接把 PID 写进目标组的 cgroup.procs;对 systemd 服务则用 set-property 作用到整个单元:
# 手工把已运行 PID 移进 v2 组(一个 PID 只能属于一个 v2 组,写入即迁移)
echo 12345 > /sys/fs/cgroup/lowpri/cgroup.procs
cat /proc/12345/cgroup # 确认 0::/lowpri
# 对 systemd 管理的服务整体限流(含其所有进程,--runtime 重启失效)
systemctl set-property --runtime nginx.service CPUQuota=200% MemoryMax=1Gv2 统一层级下每个进程同时只在一个组里,写
cgroup.procs就是迁移(会自动从原组移除);v1 每个控制器一棵树,所以 cgclassify 才需要-g cpu,memory:...同时在多棵树移动。这是两版最直观的差别。
相关命令
启动入组 cgexec、建组 cgcreate、设限 cgset、查看 cgget、列组 lscgroup。进程定位配合 ps/top/pgrep,原理见容器性能。
总结
cgclassify -g 控制器:组名 PID... = 热迁移已运行进程到 cgroup:无需重启即时改变资源归属,适合线上给失控任务降权限流;它管"存量进程",新进程用 cgexec;往更小内存组挪前先用 cgget 看用量,v2 下等价为 echo PID > cgroup.procs 或 systemctl set-property。