4、PSI指标计算原理:滑动窗口、采样聚合与时间衰减

PSI(Pressure Stall Information)的核心价值在于通过滑动窗口机制、采样聚合算法和时间衰减特性,将瞬时资源竞争转化为可量化的、具有时间维度的压力百分比。理解这三层原理,是精准设定告警阈值的前提。

4.1 三层滑动窗口:10s、60s、300s

PSI 同时维护三个时间粒度的滑动窗口,分别对应短期、中期和长期的系统压力视图。每个窗口独立记录资源 stalled 的时间占比。

窗口大小 更新周期 典型用途 告警敏感度
10s 约 2s 瞬时抖动、突发负载检测 高(易触发)
60s 约 2s 常规性能监控、中等持续时间压力 中
300s 约 10s 慢性资源泄漏、长期过载趋势 低(稳定)
关键设计原则:三个窗口并非独立运行,而是共享同一套原始 stalled 事件记录。窗口仅决定“遗忘”历史数据的速度,从而影响当前压力百分比的平滑程度。

4.2 采样与聚合算法:从 tick 到百分比

PSI 的原始数据来自内核调度器在每个 tick(通常为 4ms 或 1ms)对任务状态的采样。算法分为三步:

  1. 状态标记(tick 级):每个 tick 检查运行队列中是否有任务因等待 CPU、内存或 IO 而处于 stalled 状态。
  2. 增量累积:将 stalled tick 数累加到当前窗口的 total 计数器,同时更新 running 和 stalled 时间戳。
  3. 百分比计算:
    some_pressure = (stalled_ticks_in_window / total_ticks_in_window) × 100%
    full_pressure = (full_stalled_ticks_in_window / total_ticks_in_window) × 100%
聚合粒度说明:内核每约 2s 计算一次 10s 和 60s 窗口的百分比,每约 10s 计算一次 300s 窗口。这种非对称更新降低了高频计算开销,同时保证长窗口的统计稳定性。

4.3 时间衰减特性:指数加权移动平均(EWMA)

PSI 窗口并非简单的“先进先出”滑动窗口,而是采用指数加权移动平均(EWMA)实现时间衰减。旧数据的影响随时间呈指数级下降,而非被直接丢弃。

衰减公式核心:

new_value = (1 - decay_factor) × old_value + decay_factor × sample_value

其中 decay_factor 由窗口大小和更新周期决定:

窗口 更新周期 (Δt) 衰减因子 (α) 半衰期
10s 2s 0.2 约 3.1s
60s 2s 0.033 约 20.8s
300s 10s 0.033 约 207s
告警阈值设定启示:由于 EWMA 衰减特性,一个持续 5s 的 100% 压力事件在 10s 窗口中的峰值可能只有 60%-70%。阈值设定必须考虑窗口的“惯性”,避免因衰减导致漏报。

4.4 滑动窗口与采样聚合的协同流程

下图展示了从内核 tick 采样到用户态读取 /proc/pressure/ 文件的完整数据流:

PSI 数据流:Tick 采样 → 窗口聚合 → 用户态读取 Tick 采样 4ms/1ms 间隔 状态标记 running/stalled 增量累积 total 计数器 EWMA 滑动窗口(时间衰减) 10s 窗口 (α=0.2) 60s 窗口 (α=0.033) 300s 窗口 (α=0.033) 百分比计算 some% / full% /proc/pressure/{cpu|io|memory}

4.5 时间衰减对告警阈值的影响

理解 EWMA 的“记忆效应”是避免误配置的关键。以下对比展示了同一压力事件在不同窗口下的表现差异:

压力事件 10s 窗口峰值 60s 窗口峰值 300s 窗口峰值
持续 2s 的 100% CPU stall 约 35% 约 6% 约 1%
持续 10s 的 100% IO stall 约 85% 约 30% 约 6%
持续 60s 的 50% memory stall 约 50% 约 50% 约 25%
实践建议:若希望检测短时突发(如 5s 内的 IO 尖刺),应使用 10s 窗口并设置较低阈值(如 30%);若关注持续过载(如内存泄漏导致的缓慢增长),应使用 300s 窗口并设置较高阈值(如 10%)。切勿跨窗口直接比较数值。