PSI漂移告警阈值设定实战教程 - 第2节

PSI 数据采集原理:内核如何计算 PSI

PSI(Pressure Stall Information)是 Linux 内核 4.20 版本引入的资源压力指标,用于量化 CPU、内存和 IO 资源不足对任务执行造成的延迟。理解 PSI 的内核采集原理,是正确设定告警阈值的前提。

内核计算 PSI 的核心机制

PSI 的计算基于 任务状态跟踪 和 时间累积 两个核心环节。内核调度器在每次任务状态切换时,记录任务因等待资源而停滞的时间,并按时间窗口聚合为百分比压力值。

关键概念: PSI 不是采样统计,而是全量事件驱动的时间累积。内核在每次调度 tick 或任务状态变更时,都会精确记录等待时间,因此数据精度远高于传统的 /proc/stat 采样方式。

PSI 的三种资源维度与任务状态

内核为 CPU、内存、IO 三种资源分别维护独立的压力跟踪器。每个跟踪器关注两类任务状态:

资源维度 跟踪状态 含义
CPU running / runnable 任务处于可运行队列但未获得 CPU 时间片
Memory stalled / waiting 任务因缺页、内存回收或 swap 而阻塞
IO stalled / waiting 任务因等待块设备 IO 或文件系统操作完成而阻塞

每个跟踪器内部维护两个关键计数器:

  • total 计数器:自系统启动以来,任务处于“停滞”状态的总微秒数。
  • 时间窗口滑动平均:基于最近 10 秒、60 秒、300 秒三个窗口的加权平均压力百分比。

PSI 时间窗口机制

内核使用 指数加权移动平均(EWMA) 算法计算三个时间窗口的压力值。每个窗口的衰减因子不同,使得短窗口对瞬时尖峰更敏感,长窗口反映长期趋势。

窗口选择建议: 告警阈值设定通常以 60 秒窗口(avg60)为主,10 秒窗口用于检测突发抖动,300 秒窗口用于容量规划。漂移检测应优先关注 avg60 的连续变化趋势。
PSI 时间窗口滑动平均计算流程 内核调度事件 任务状态变更:记录等待时间 10s 窗口 EWMA 60s 窗口 EWMA 300s 窗口 EWMA some / full 压力百分比 some / full 压力百分比 some / full 压力百分比 每个窗口独立计算 some(至少一个任务停滞)和 full(所有任务停滞)两个压力值

/proc/pressure 目录详解

内核通过 /proc/pressure 伪文件系统向用户空间暴露 PSI 数据。该目录下包含三个文件,分别对应 CPU、内存、IO 的压力指标。

文件结构与字段说明

每个文件的内容格式统一,以 /proc/pressure/cpu 为例:

some avg10=0.00 avg60=0.00 avg300=0.00 total=0
字段 类型 说明
some 标签 表示至少有一个任务因资源不足而停滞
full 标签 表示所有非空闲任务都因资源不足而停滞(仅内存和 IO 文件包含此字段)
avg10 浮点数 最近 10 秒窗口的压力百分比(0.00 ~ 100.00)
avg60 浮点数 最近 60 秒窗口的压力百分比
avg300 浮点数 最近 300 秒窗口的压力百分比
total 整数 自系统启动以来,任务停滞的总微秒数(单调递增)
注意: CPU 压力文件只包含 some 行,不包含 full 行。因为 CPU 资源无法被所有任务同时完全阻塞(总有 idle 任务或内核线程可以运行)。内存和 IO 压力文件则同时包含 some 和 full 两行。

三个压力文件的差异对比

文件路径 资源类型 some 行 full 行 典型触发场景
/proc/pressure/cpu CPU ✓ ✗ CPU 密集型任务争抢时间片
/proc/pressure/memory 内存 ✓ ✓ 内存回收、swap 抖动、OOM 边缘
/proc/pressure/io IO ✓ ✓ 磁盘 IO 瓶颈、文件系统锁竞争

some 与 full 的语义差异

理解 some 和 full 的区别,对于设定告警阈值至关重要:

  • some:至少一个任务因资源不足而停滞。表示资源存在竞争,但系统仍能部分推进工作。
  • full:所有非空闲任务都因资源不足而停滞。表示资源严重短缺,系统整体吞吐量大幅下降。
告警阈值策略: 对于 IO 和内存,建议同时监控 some 和 full。当 full 值持续超过 1% 时,通常意味着系统已经进入严重过载状态,需要立即介入。而 some 值在 5%~10% 范围内波动,可能只是正常资源竞争。

PSI 时间窗口机制深入

内核的 EWMA 算法使得 PSI 值既能快速响应突发压力,又能平滑短期波动。理解窗口的衰减特性,有助于选择合适的窗口进行漂移检测。

EWMA 衰减因子与窗口长度

每个时间窗口对应一个固定的衰减因子 α,计算公式为:

α = 1 - exp(-Δt / window_length)

其中:
- Δt 为采样间隔(通常为内核调度 tick,约 4ms)
- window_length 为窗口长度(10s / 60s / 300s)
窗口 衰减因子 α(近似) 半衰期 对突发响应速度
10s 0.0004 ~7s 快:秒级响应尖峰
60s 0.000067 ~42s 中:分钟级跟踪趋势
300s 0.000013 ~208s 慢:反映长期负载

窗口选择与漂移检测的关系

在 PSI 漂移告警场景中,不同窗口承担不同角色:

  • avg10:用于检测瞬时压力尖峰,适合设置紧急告警(如 > 70% 持续 10 秒)。
  • avg60:漂移检测的主窗口。连续多个采样周期内 avg60 的缓慢上升,是资源瓶颈恶化的典型信号。
  • avg300:用于基线对比和容量规划。当 avg300 趋势线开始向上偏离历史基线时,表明系统正在进入新的压力常态。
实战建议: 漂移告警应基于 avg60 的滑动差分值。例如,计算当前 avg60 与 5 分钟前 avg60 的差值,若连续 3 次采样差值 > 0.5%,则触发漂移告警。这种方法能有效过滤瞬时抖动,聚焦于趋势变化。
PSI 三个时间窗口对同一压力事件的响应对比 0% 50% 100% 0s 30s 60s 90s 120s 10s 窗口 60s 窗口 300s 窗口 10s 窗口对 80% 压力脉冲响应最剧烈,60s 窗口平滑后峰值约 40%,300s 窗口几乎不受影响

PSI 数据采集的注意事项

  • 内核版本要求:PSI 功能需要 Linux 内核 4.20+,且编译时需开启 CONFIG_PSI=y。可通过 cat /boot/config-$(uname -r) | grep CONFIG_PSI 确认。
  • 读取开销:读取 /proc/pressure/* 文件是 O(1) 操作,不会产生额外内核开销,适合高频采集(如 1 秒一次)。
  • total 字段的用途:total 是单调递增的微秒计数器,可用于计算两个时间点之间的平均压力,公式为 (total2 - total1) / (time2 - time1) / 1000000 * 100。
  • cgroup v2 支持:PSI 同样支持 cgroup v2 层级,可在 /sys/fs/cgroup/<cgroup_path>/cpu.pressure 等路径下获取容器级别的压力数据。
采集频率建议: 对于漂移告警场景,建议采集间隔为 10~30 秒。过高的频率(如 1 秒)会产生大量噪声数据,增加存储和计算开销;过低的频率(如 5 分钟)则会丢失漂移趋势的细节。