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)对任务状态的采样。算法分为三步:
- 状态标记(tick 级):每个 tick 检查运行队列中是否有任务因等待 CPU、内存或 IO 而处于 stalled 状态。
- 增量累积:将 stalled tick 数累加到当前窗口的
total计数器,同时更新running和stalled时间戳。 - 百分比计算:
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/ 文件的完整数据流:
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%)。切勿跨窗口直接比较数值。