首页 / 资讯中心 / 文章详情

内核卡顿先看增量:一份不会上来就关 THP 的排障记录

内核卡顿先看增量:一份不会上来就关 THP 的排障记录 ★ FEATURED ARTICLE
看到khugepaged出现在采样里就把 THP 全关掉很容易把排障变成猜参数。compact_stall在一张截图里很大也可能只是机器已经运行了很久。没有时间窗口累计值不能告诉我们这一分钟发生了什么。这篇用构造日志讲排查步骤不写成一次发生过的生产事故。真实系统的证据应包含同一时间窗的延迟、CPU、内存压力、内核栈与计数器变化而不是先给一个惊险故事再替故事找命令。从两个快照开始Linux 的 THP 文档还讨论了 multi-size THP不是所有透明大页都只能按“2MB 对 4KB”解释。可用大小与启用方式取决于实际系统。文档也提醒某些MADV_COLLAPSE行为不被普通 sysfs 的 never 设置完全覆盖因此“写入 never 就永久关闭一切 THP”过于绝对。官方说明先记录内核版本与/proc/vmstat的两个快照把差值除以间隔得到速率。若发生计数回退可能是重启或输入不一致应中止当前比较而不是把负数当成性能改善。什么证据能支持 THP 假设内存规整计数上涨只是线索。还需要看延迟尖峰是否同窗、采样栈是否落在相关路径、压力是否来自其他内存回收。然后在可以回滚的对照环境里改变一个条件。样例不执行任何内核写操作也不提供脱离版本条件的调参套餐。图把累计计数、增量与速率分开。两个快照中的数值是教学输入不代表服务器的真实基线也不能单独证明 THP 导致了请求停顿。def parse_vmstat(text): result {} for line in text.splitlines(): fields line.split() if len(fields) ! 2 or fields[0] in result: raise ValueError(invalid or repeated counter) value int(fields[1]) if value 0: raise ValueError(negative counter) result[fields[0]] value return result def rates(before, after, seconds): if seconds 0: raise ValueError(positive observation interval required) result {} for key in before.keys() after.keys(): delta after[key] - before[key] if delta 0: raise ValueError(counter reset: key) result[key] delta / seconds return result before parse_vmstat(compact_stall 100\nthp_collapse_alloc_failed 8) after parse_vmstat(compact_stall 130\nthp_collapse_alloc_failed 10) r rates(before, after, 10) assert r {compact_stall: 3.0, thp_collapse_alloc_failed: 0.2} try: rates(after, before, 10) except ValueError: pass else: raise AssertionError(reset was interpreted as improvement) print(compact_stall3.0/s; collapse_failed0.2/s; reset rejected)例子跑通以后还要验证什么这段代码已在本地 macOS、CPython 3.9.6 下运行实际输出为compact_stall3.0/s; collapse_failed0.2/s; reset rejected。它验证的是例子中的数据约束与分支不包含线上服务的吞吐或延迟测量。本地仅运行文本解析与差分逻辑没有读取宿主机 Linux 指标、执行 perf 或更改 sysfs。真正定位需要业务延迟与内核证据的时间对齐以及适合该发行版的观测手段。关闭功能后的改善也要检查吞吐、内存占用和后续回归不能只看一次 P99。延伸阅读Linux Transparent Hugepage SupportTHP 大小、控制方式与行为边界的依据。
阅读完成 · 觉得有帮助?
咨询建站