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 的连续变化趋势。
/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 数据采集的注意事项
- 内核版本要求: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 分钟)则会丢失漂移趋势的细节。