cgroup v2 memory.high怎么配置或排查
来源:17golang原创
时间:2026-09-13 04:50:04 420浏览 收藏
很多运维和开发同学刚接触cgroup v2的时候,经常碰到memory.high参数配置完没效果,或者业务进程没到硬限制就被触发内存回收的情况,顺着常规配置步骤和排查路径走,基本都能定位到问题。
配置cgroup v2的memory.high前要先确认当前系统已经启用cgroup v2统一层级,排查时优先核对当前cgroup目录下的内存统计项、当前触发的水位阈值,再逐层校验父cgroup的配置继承规则即可。
如果服务进入 cgroup v2 后只是变慢,却没有被 OOM 杀掉,先看 memory.high。它是“超过后施加回收压力并节流”的边界,默认值是 max;真正的硬内存上限是 memory.max。因此排查重点不是盯着一个剩余内存数字,而是确认进程归属、当前用量、high 事件以及内存压力是否同时出现。
memory.high超限会让该 cgroup 承受直接回收和节流,通常不会直接触发 OOM killer。- 直接写 cgroup 文件时使用字节数;例如 512 MiB 应写成
536870912,不是带单位的字符串。 memory.events.local看本组,memory.events还会包含子树;两者都要和memory.stat、memory.pressure对照。
memory.high 控制的是节流,不是 OOM
Linux 内核把 memory controller 的几个边界分成了不同职责。memory.low 和 memory.min 是回收保护,memory.high 是超限后的节流边界,memory.max 才是无法回收时可能进入 cgroup OOM 的硬限制。把二者混用,是“服务没有退出却延迟暴涨”这类现象最常见的起点。
| 接口 | 作用 | 排查时关注什么 |
|---|---|---|
memory.high | 超过后加大回收压力并节流 | memory.events(.local) 的 high |
memory.max | 无法回收时限制用量,可能触发 OOM | max、oom、oom_kill |
memory.current | 当前 cgroup 及其后代的内存用量 | 是否持续越过 high 边界 |
这也解释了一个容易误判的结果:memory.current 高于 memory.high 并不等于设置失败。高边界允许在极端情况下被暂时突破,关键证据是工作负载是否被持续节流,以及事件计数是否增长。
先把 memory.high 写进正确的 cgroup
先确认统一层级和控制器是否可见,再确认目标 PID 的归属。下面的示例只针对已经存在的 cgroup v2 挂载点;变量写法方便在测试机上替换目录,不要把宿主机根 cgroup 当成业务组直接修改。
# 确认 cgroup v2 挂载点和 memory 控制器是否可见
CG=/sys/fs/cgroup/demo-app
test -f /sys/fs/cgroup/cgroup.controllers || { echo "不是预期的 cgroup v2 根目录"; exit 1; }
grep -qw memory /sys/fs/cgroup/cgroup.controllers || { echo "memory 控制器不可用"; exit 1; }
# 直接写入 cgroup 文件时使用字节数:512 MiB = 536870912 字节
HIGH_BYTES=$((512 * 1024 * 1024))
printf '%s\n' "$HIGH_BYTES" | sudo tee "$CG/memory.high" >/dev/null
cat "$CG/memory.high"
# 先确认目标进程确实属于该组,再观察它的后续行为
PID=12345
grep -q "0::/demo-app" "/proc/$PID/cgroup" || { echo "PID 不在目标 cgroup"; exit 1; }
printf '%s\n' "$PID" | sudo tee "$CG/cgroup.procs" >/dev/null
如果 memory.high 不存在,通常不是“参数拼错”,而是 memory 控制器没有在父级的 cgroup.subtree_control 中启用,或者目标目录不是你以为的 v2 层级。cgroup v2 的控制器启用遵循自上而下的约束,先看 cgroup.controllers 和父目录的 cgroup.subtree_control,再处理权限。

memory.events 和 PSI 怎么定位瓶颈
设置完成后不要只重复读取阈值。memory.current 回答“现在用了多少”,memory.events.local 回答“本组发生了什么”,memory.stat 帮你拆分匿名内存、文件缓存、内核和 socket,memory.pressure 则反映任务因内存不足而等待的压力。
# 读取同一 cgroup 的用量、局部事件和压力;命令只读不修改配置
CG=/sys/fs/cgroup/demo-app
printf 'memory.current='; cat "$CG/memory.current"
printf '\nmemory.high='; cat "$CG/memory.high"
printf '\nmemory.max='; cat "$CG/memory.max"
# local 只看本组,memory.events 则可能包含后代 cgroup 的计数
cat "$CG/memory.events.local"
# 按键名读取统计,避免依赖 memory.stat 的显示顺序
awk '$1 ~ /^(anon|file|kernel|sock|shmem)$/ { print }' "$CG/memory.stat"
cat "$CG/memory.pressure"
判断可以按这个顺序进行:如果 memory.current 接近或超过 memory.high,同时 memory.events.local 的 high 增长,说明本组确实反复进入高边界节流;如果只有 memory.events 增长而 local 不变,优先检查子 cgroup。若 max、oom 或 oom_kill 增长,问题已经越过 memory.high,应该回到 memory.max 与工作负载峰值排查。
memory.stat 还能缩小方向:anon 持续上升更像进程堆或匿名映射增长,file 偏高则要看页缓存和 tmpfs,kernel、sock 异常时不要只调高应用阈值。PSI 的 some 或 full 持续升高,才说明节流已经转化为可感知的等待;单独一次 high 计数不能代表服务一定需要更多内存。

常见问题
memory.high 可以直接写 512M 吗?
直接写 cgroup v2 接口时按内核文档使用字节数,建议先用 shell 算出整数再写入。systemd 的 MemoryHigh=512M 属于上层配置语法,不能据此推断底层文件也接受相同单位。
为什么 memory.current 超过 memory.high 还没有被杀?
这是预期语义。memory.high 主要触发回收压力和节流,不负责直接调用 OOM killer;需要硬上限时才检查 memory.max,并同时观察 oom 相关事件。
应该读 memory.events 还是 memory.events.local?
要判断当前目录自身,优先读 local;要观察整棵子树,读 memory.events。两者的层级口径不同,混着比较会把子服务的 high 事件误算到当前服务。
实际调参时,先记录业务低峰和峰值下的四组证据,再逐步调整 memory.high;不要用一次偶发计数替代持续压力判断。若由 systemd 管理服务,还应把 unit 的 MemoryHigh/MemoryMax 与实际 cgroup 文件对应起来,避免运行时手改被下一次部署覆盖。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习