深夜的市立医院急诊科,分诊台前人流涌动。门口挂着一块木质告示牌,上面只有一行数字:“今日累计接诊 356 人”。护士长林姐却皱着眉——她真正想知道的是:此刻候诊区有多少病人已经等了超过 20 分钟?呼吸科走廊里是不是已经挤满了咳嗽的患者?ICU 门口是不是有家属因床位紧张而焦躁不安?这些“正在等待”的信息,才是判断急诊是否饱和的关键。这块告示牌,就像 Linux 系统里古老的 load average,告诉你“有多少人来看过病”,却看不见“还有多少人正在痛苦等待”。而 PSI(Pressure Stall Information,压力停滞信息)指标,就是林姐手上那份实时更新的“候诊压力台账”——它精确记录 CPU、内存、磁盘 I/O 三类资源面前,每个“病人”(任务)究竟等了多久,是只有几个人在排队,还是所有人都被堵在门口。
对 AI 从业者而言,PSI 是读懂云原生容器、推理服务、大数据作业“卡顿根源”的听诊器。掌握 PSI,你就能从系统负载的迷雾中,精准定位 CPU 算力饥饿、内存分配停滞还是磁盘 I/O 阻塞,为模型服务的自动扩缩容和故障诊断提供量化依据。
可视化演示
通过三类资源压力仪表、some/full语义对比和聚合指标与cgroup监控三个模式,展示PSI指标体系的核心原理。
本节配有交互动效(进入视口后自动加载,约 3KB)。
CPU/内存/I/O三类资源压力指标 CPU压力低(~15%),内存中等(~35%),I/O最高(~60%) 每类资源有some和full两个维度,超阈值触发告警 PSI = {cpu,mem,io} × {some,full} × {avg10,avg60,avg300} PSI量化资源竞争导致的任务停滞时间,比负载均值更精确
PSI诞生背景
急诊科门口那块“今日累计接诊”的木牌,和 Linux 经典的 load average 如出一辙。load 告诉系统管理员“当前有多少任务在排队”,但它从不告诉你这些任务已经等了多久、等的是哪类资源。当一台机器上跑着 50 个容器、上千个线程时,load 数字像一块发烫的体温计——你只知道“有点热”,却分不清是 CPU 发烧、内存缺氧还是磁盘堵车。这正是 PSI 诞生的直接原因:面对日益严重的多租户资源竞争,内核需要一个能精确量化“任务正在被哪种资源饿肚子”的探针。
2018 年,Google 的工程师将 PSI 合入 Linux 内核 4.20。它的设计哲学朴素而深刻:不统计“资源有多忙”,而统计“任务有多饿”。想象一下,医院的告示牌不应该是“全科医生坐诊率 85%”,而应该是“呼吸科已有 12 位病人在走廊等待超过 30 分钟”——后者才是真正影响患者体验的指标。PSI 在内核调度器、内存分配器和块设备层埋入采样点,每当一个任务因等待而无法推进,就记录一段“停滞时长”。
这就是 PSI 的定位——林姐需要的不是“医生几点下班”,而是“病人几点才能看上病”。系统管理员同样需要从“资源繁忙”的视角,切换到“任务停滞”的视角,才能抓住真正影响业务的痛点。
- 利用率定义
util表示资源忙碌占比,只看设备本身的工作强度。 - 分子含义
T_busy是设备处于工作状态的累计时间,比如 CPU 执行指令的总时长。 - 分母含义
T_total是观测窗口的总时长,它是整个指标的统一坐标系。 - 局限对比忙但无人等待时 util 高、PSI 低;不忙却大量任务排队时 util 低、PSI 高,这正是 PSI 要补的盲区。
压力指标内涵
分诊台护士每看到一位新病人,就在台账上记下“到达时间”。如果病人 20 分钟还没被叫到号,林姐就画一个红圈——这个红圈不是病人本身,而是“病人等待的 20 分钟”。PSI 的核心思想正是如此:它衡量的不是“资源状态”,而是“任务等待资源的累积时间”。每当一个任务因为 CPU 算力不足、内存分配延迟或磁盘 I/O 阻塞而无法前进,内核就在 PSI 计数器上累加这段等待。
具体来说,PSI 会持续观察一组任务(默认是系统内所有任务),统计它们在“可运行但没拿到 CPU”“等待内存页分配”“等待块设备完成读写”三种状态下被卡住的时间。然后,把这些等待时间累加起来,除以总观测时长,得到一个百分比——这就是压力值。这个百分比非常直观:10% 意味着平均每 10 秒中有 1 秒至少有一个任务在“干着急”。
回到比喻:压力值就像候诊台账上的“红圈率”。如果过去 5 分钟内有 3 位病人等待超过 20 分钟,林姐就知道分诊台需要加派人手了。同理,当你看到 memory 压力达到两位数,就该意识到当前内存分配速度已经拖慢了不少任务,而不是等到 OOM(内存耗尽)才被动应对。
- 分子累加
Σ T_blocked对所有任务、所有阻塞事件求和,把零碎的等待片段拼成总饥饿时间。 - 分母基准
T_observe是观测窗口的时长,保证不同窗口的数据可比。 - 百分比换算相乘 100% 后,压力值被归一化到 0-100 的整数区间,便于配置阈值。
- 设计意图同一个归一化标准,可以平等地比较 CPU、内存、IO 三类资源的“拥挤程度”。
some与full语义
深夜的急诊室,林姐在台账上标了两栏:一栏是“至少有一个病人在等”,另一栏是“所有病人都堵在候诊区,一个都看不上病”。第一栏,对应 PSI 的 some;第二栏,对应 full。这两种语义描绘的压力烈度截然不同——some 意味着部分任务被拖慢,系统仍在“带病运行”;full 意味着所有任务都被卡死,业务几乎停摆。
PSI 对每一类资源都会输出 some 和 full 两行统计,但唯独 CPU 例外。为什么?因为 CPU 只有一个执行单元,当所有任务都在等待 CPU 时,CPU 实际上处于空闲状态,这与系统无事可做的 idle 状态无法区分。换句话说,CPU 级别的 full 在语义上等价于“全体停摆”,但这种状态无法被采样点感知到。因此 /proc/pressure/cpu 只有 some,而 memory 和 io 都同时拥有两行。
在云原生环境里,这个语义差异极具诊断价值:如果 io 的 some 很高但 full 很低,说明只是部分容器在争抢磁盘 I/O;如果 full 逼近 some,那所有人的业务都堵在存储层了。林姐看一眼“是否全员滞留”,就能判断是该增派医生还是启动应急预案——这正是 PSI 双语义设计的精妙之处。
- some 的分子
T_至少一个任务阻塞统计任意时刻至少有一个任务在等待资源的累计时长。 - full 的分子
T_全部任务阻塞只统计所有任务同时被阻塞的时间段,条件更苛刻。 - 包含关系全阻塞的时间必然包含在部分阻塞的时间中,因此 P_full ≤ P_some 恒成立。
- CPU 特例满员等待时 CPU 与 idle 不可区分,故 CPU 不输出 full。
平均窗口机制
候诊台账如果只记录“此刻等待人数”,数字会像心跳一样剧烈跳动,很难看出趋势。于是林姐让护士同时维护三块表:过去 10 秒的平均候诊数(用于快速预警)、过去 60 秒的平均数(用于中期判断)、过去 300 秒的平均数(用于评估整体走势)。PSI 的 avg10、avg60、avg300 正是同样的三档滑动窗口。
这三档窗口并非简单地把窗口内的样本求算术平均,而是采用指数加权移动平均(EWMA)——越靠近当前时刻的数据权重越大,遥远的历史数据权重指数级衰减。这样做的好处是:既能快速响应突发的资源争抢,又不会被短暂的毛刺完全带偏。内核周期性采样压力值,每一轮都用新样本更新这三个平滑值。
阅读 PSI 数据时,林姐的习惯是“三表联看”:avg300 高而 avg10 低,说明是过去的老账,当前已缓解;avg10 突然飙升而 avg300 平稳,说明是刚刚发生的高峰;三档齐高,则是持续性的严重压力。运维人员同样可以依据这个组合判断是突发抖动还是慢性饥饿,从而决定是立即扩容还是继续观察。
- 当前样本
s_n是这一轮采样周期内测得的瞬时压力值,是更新的原料。 - 历史记忆
avg_{n-1}是上一轮的综合平均值,承载着整个历史的信息。 - 融合权重
α是平滑系数,三档窗口内部使用不同 α 来匹配响应速度。 - 递推演化整个公式是一个递推过程,当前值由新样本与旧平均值共同决策,无需保存全部历史数据。
cgroup级聚合
大医院的急诊科不能只有一张全院总台账。林姐需要在每个病区——ICU、儿科、外科——各放一个分诊台,每个分诊台记录本区域的候诊压力;同时,院长办公室还保留着一张全院汇总表,由上而下逐级嵌套。Linux 的 cgroup 层级结构与这个组织架构完美同构:每个容器、每个业务分组都是树上的一个节点。PSI 从 Linux 4.20 开始支持 cgroup 级统计,每个 cgroup 节点都可以读取属于自己的压力文件。
这种“逐级聚合”是如何实现的?内核为每个 cgroup 节点独立维护一套 PSI 计数器,当子 cgroup 中的任务发生资源等待时,事件同时向父节点逐级上报。父节点的压力值不是简单的子节点数值相加,而是按时间轴做“并集”合并——只要子节点中有任何一个任务在等待,父节点在那个时刻就记为“有任务等待”。
有了 cgroup 级聚合,林姐的“分诊台”就能下沉到每个病区了。在 Kubernetes 集群里,你可以对单个 Pod 的 cgroup 读取 PSI,精准判断是哪个业务的容器在“霸占候诊区”,进而实现租户级的监控和告警。这就是 PSI 演进到 cgroup 后的核心价值:把宏观判断升级为微观定位。
- 子节点事件
等待事件_c表示子节点 c 内部发生的任务阻塞时刻集合,是一个时间轴上的区间。 - 并集合并
∪把所有子节点的等待区间取并集,重叠部分只计一次,反映真实的多租户叠加效果。 - 归一化分母仍然除以总观测时长
T_total,让聚合后的压力值与全局口径保持一致。 - 层级递归这个公式在树的每一层重复,从叶子容器一路汇总到根节点,形成完整的压力地图。
监控告警实践
有了 cgroup 级台账,林姐在护士站装了一块大屏,三行数字滚动更新:CPU 候诊、内存候诊、磁盘候诊。她还设了两道警戒线:黄线表示“关注区”,红线表示“危机区”。系统每 10 秒刷新一次数据,一旦某个资源的 avg10 越过红线,大屏立即闪烁并给值班医生发送消息。这就是一套基于 PSI 的监控告警闭环。
在实现层面,数据来源非常简单——Linux 内核把 PSI 统计暴露在 /proc/pressure/ 目录下,分别是 cpu、memory、io 三个文件。监控系统(如 Prometheus 的 node_exporter)周期性地读取这些文件,把 avg10、avg60、avg300 和 total 字段采集到时序数据库中。阈值设置的经验法则是:CPU some 超过 30% 意味着明显算力饥饿,IO full 超过 5% 就可能造成业务抖动。
但林姐很快提醒护士们:单看当前数字会误诊。高 avg300 且低 avg10 意味着这是一场“已经结束的拥堵”;反之突然飙升的 avg10 才需要立即处理。监控系统也应把趋势数据作为告警条件之一,比如“avg10 在 3 分钟内持续上升超过 20%”,这样的规则能有效减少误报。这就是趋势研判的价值。
- 告警信号
Alert是布尔量,1 表示需要报警,0 表示安全。 - 对比条件
avg10 ≥ T_critical表示最近 10 秒的压力值超过临界阈值,这是最敏感的快速通道。 - 分档处理实践中常把阈值设为多级,如 Warning 与 Critical,对应不同响应力度。
- 闭环动作告警不仅喊人,还可联动系统自动记录现场、dump 堆栈,为事后分析留存证据。
自动扩缩容实战
林姐最骄傲的革新,是给急诊科装了一套“弹性调度系统”:当候诊压力超限,系统自动开启一个临时诊室;当压力回落,自动关闭空闲诊室。这套逻辑映射到云原生平台,就是基于 PSI 的自动扩缩容。相比传统的基于 CPU 利用率的策略,PSI 直接感知“任务是否被饿着”,避免了一个典型陷阱:CPU 利用率 30% 但任务大量阻塞在高延迟磁盘上——只看 CPU 利用率永远发现不了问题。
扩缩容决策的核心是“三看”:看阈值、看趋势、看冷却。阈值设定为扩容触发条件,比如 cpu.some.avg10 > 40;趋势判断防止单次毛刺引发误扩;冷却时间(防抖)则保证每一次扩缩之间留有至少 5-10 分钟的稳定期,避免“刚扩完又缩、缩完又扩”的震荡。
自动扩缩容的比喻非常好懂:林姐的弹性系统不是“人多就开门、人少就关门”的机械反应,而是有耐心、有节律的调度。她会给系统设置一个观察期,确认急诊确实处于持续高压才启动临时诊室;同样,云平台在 PSI 指标触发扩容后,也会等待部署顺利完成、压力真正缓解,再考虑缩容。这样的策略让资源利用率和业务稳定性都达到了最优解。
- 扩容分支
+1表示增加一个副本节点,条件是压力值P_avg10不低于扩容阈值T_up。 - 缩容分支
-1表示减少一个副本节点,条件是压力值不高于缩容阈值T_down(通常远低于扩容阈值)。 - 冷却闸门
(t - t_last) ≥ τ是通用的时间约束,两次动作之间必须间隔至少 τ 分钟。 - 保持默认以上条件均不满足时,副本数保持为上一时刻的值
S(t-1),系统平稳过渡。
PSI与Load对比
急诊科门口那块“累计接诊”木牌,终于要接受一次全面审视了。load average 显示的是“正在排队 + 正在服务”的任务总数,它像一块简单的计数牌;而 PSI 的屏幕上是候诊区每个病人等待时长的实时统计。两者最大的区别在于:Load 不区分“这一个人”在等什么资源,更不记录等待时长;PSI 则同时提供了资源类型、等待烈度(some/full)和时间维度(avg10/60/300)。
举个例子:一台机器 Load 高达 60,如果你只看这个数字,可能以为 CPU 严重超载。但用 PSI 一查,CPU 的 some 只有 5%,IO 的 some 却高达 45%——原来是磁盘成为瓶颈,CPU 正闲着等 I/O 返回。这种“张冠李戴”的误判,在传统的 Load 视角下经常发生。因此,两者是互补关系:Load 给你整体繁忙度的第一印象,PSI 帮你精准定位拥堵的真源头。
在林姐的急诊科,她和那块木牌“和解”了:木牌记录就诊人数,评估医院整体繁忙度;而新台账定位瓶颈、量化等待、驱动调度。系统管理员也一样——uptime 里的 Load 不会消失,但它不再是决策的唯一依据。用 PSI 作为精细化诊断工具,与 Load 形成组合拳,才是一个现代运维者应有的指标素养。
- Load 两项
N_runnable是可运行但未获得 CPU 的任务数,N_uninterruptible是不可中断睡眠(通常等待 I/O)的任务数。 - 快照特性Load 是采样瞬间的排队人数,不包含“这些人已经等了多久”的信息。
- PSI 函数
f(T_blocked, 资源类型)表示 PSI 是等待时间的函数,并且按 CPU、内存、IO 分门别类。 - 互补使用Load 高 + PSI 全面高 = 整体饱和;Load 高 + 某类 PSI 高 = 该资源为瓶颈。
AI 应用场景
云原生容器平台的租户级监控
阶段:数据采集与监控告警
解决的问题:传统监控只看节点级 CPU/内存利用率,无法回答“哪个容器的任务在等待资源”。当一个节点上运行几十个 Pod,某个容器疯狂刷磁盘会导致其他容器 I/O 停滞,而节点总利用率却不见异常。PSI 的 cgroup 级聚合能把压力精确到每个 Pod,量化每个租户的资源饥饿程度。
具体案例:某 SaaS 平台将 node_exporter 采集到的 Pod 级 io.some.avg300 接入 Prometheus,配置 15% 阈值告警。一次故障中,告警精准定位到某个数据分析容器正在反复刷新大表缓存,导致同节点上支付容器 I/O 等待从 2% 飙到 23%。团队 5 分钟内完成了问题定位与容器隔离。
推理服务的弹性伸缩增强
阶段:模型部署与容量管理
解决的问题:GPU 推理服务的瓶颈常在 CPU 预处理、内存拷贝或磁盘模型加载,而非 GPU 算力。基于 CPU 利用率的扩缩容策略对这类“隐性饥饿”反应迟钝。PSI 指标直接反映任务被资源阻塞的程度,作为 HPA(水平自动伸缩)的自定义指标,能更准确地匹配推理延迟的恶化曲线。
具体案例:某大模型 API 服务为 preprocessing 容器配置了基于 cpu.some.avg10 > 35 的扩容规则。压测中 200 个并发请求使 CPU 压力飙升,系统在 10 秒内扩展出 3 个新副本,P99 延迟从 2.8 秒回落至 900 毫秒,而传统 CPU 利用率策略则迟到了近 1 分钟。
混部集群的干扰检测
阶段:性能排障与资源隔离
解决的问题:在线业务与离线批处理任务混部时,离线任务对 CPU 缓存、内存带宽、磁盘队列的抢占会产生“噪声干扰”,令在线服务的尾延迟显著恶化。这种干扰在利用率指标上几乎不可见,但 PSI 的 some 与 full 差值能揭示部分任务被抢占的真相。
具体案例:某互联网公司在大数据离线作业运行时,观察到在线服务的 TP99 上升 40%。通过部署 PSI Exporter,发现 cpu.some.avg10 从 5% 跃升至 28%,而 full 仅为 2%——典型的“部分任务被离线作业饿着”。据此精确下调离线作业的 cgroup CPU 份额,在线延迟恢复正常。
Python 演示
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""psi_probe.py - 读取 PSI 指标并输出扩缩容建议"""import time def read_psi(path): result = {} with open(path, encoding='utf-8') as fp: for line in fp: parts = line.strip().split() key = parts[0] metrics = {} for token in parts[1:]: name, value = token.split('=') metrics[name] = int(value) if name == 'total' else float(value) result[key] = metrics return result def get(psi, scope, metric='avg10'): if scope in psi and metric in psi[scope]: return psi[scope][metric] return 0.0 def decide(cpu, mem, io, cpu_thr, mem_thr, io_thr): c = get(cpu, 'some') m = get(mem, 'full') i = get(io, 'some') peak = max(c, m, i) if peak > max(cpu_thr, mem_thr, io_thr): return 'scale_out', '峰值压力 %.1f%% 超过阈值,建议扩容' % peak if c < cpu_thr * 0.3 and m < mem_thr * 0.3 and i < io_thr * 0.3: return 'scale_in', '压力均低于阈值 30%%,可以缩容' return 'hold', '压力在阈值内,保持现状' def main(): while True: try: cpu = read_psi('/proc/pressure/cpu') mem = read_psi('/proc/pressure/memory') io = read_psi('/proc/pressure/io') except FileNotFoundError: print('未找到 PSI 接口,请确认内核版本 >= 4.20 且开启 CONFIG_PSI') return action, reason = decide(cpu, mem, io, 10.0, 10.0, 10.0) print('[%s] cpu(some)=%.2f mem(full)=%.2f io(some)=%.2f -> %s %s' % ( time.strftime('%H:%M:%S'), get(cpu, 'some'), get(mem, 'full'), get(io, 'some'), action, reason)) time.sleep(2) if __name__ == '__main__': main()
/proc/pressure/ 下的三个 PSI 指标文件,解析 some/full 的 avg10 值,按阈值规则给出扩容、缩容或保持的建议。read_psi(path)解析 PSI 文本文件,把每行拆成some/full两个作用域,每个作用域内再拆出 avg10、avg60、avg300、total 键值对。metrics[name] = int(value) if name == 'total' else float(value)total 字段是累计微秒数,用整数存储;其余平均字段是浮点百分比。get(psi, 'some')安全地获取指定作用域的平均压力值,缺失时返回 0,避免 KeyError。peak = max(c, m, i)取 CPU、内存、IO 三者压力的最大值为决策依据,防止单点瓶颈被平均值掩盖。if peak > max(cpu_thr, mem_thr, io_thr)只要任一资源压力突破对应阈值,就触发扩容动作。if c < cpu_thr * 0.3 and ...三路压力都低于阈值的 30%,才判定为低峰期,可安全缩容。time.sleep(2)每 2 秒采样一次,兼顾实时性与系统开销,实际生产可配置为 5-10 秒。
常见误区
误区PSI 的 CPU 压力值高,不就是 CPU 使用率高吗?那我直接用 top 看 %CPU 不就行了?
正解两者统计口径完全不同。CPU 利用率统计的是“CPU 在工作的时间占比”,而 PSI 统计的是“任务在等待 CPU 的时间占比”。一个双核机器上跑着 100 个线程,CPU 利用率可能只有 40%,但所有线程都在极其频繁地抢时间片排不上队,此时 cpu.some.avg10 可能高达 60%。用急诊室的话说,利用率回答“医生有多忙”,PSI 回答“病人等得有多苦”——医生很闲但病人都在排队的情况完全存在。
为何常见:top 命令太常见了,人脑天然倾向于用熟悉的“忙闲”概念解释新的百分比指标,忽略了 PSI 的“等待/停滞”本质。
误区`some` 和 `full` 是不是两种资源?`full` 高是不是意味着发生了某种特殊的“full 型死锁”?
正解some 和 full 不是两种压力源,而是同一份阻塞事件在不同严重程度下的统计口径。some 记录“至少一个任务在等”,full 记录“所有任务都在等”。它们是同一段历史数据的两种切法,就像“候诊区有人等待”和“候诊区全员滞留”描述的是同一个急诊室的两种状态。理解这一点对判读至关重要:some 与 full 的差值越大,说明只有部分任务受影响,系统还有余力;两者重合度越高,说明是全局性瘫痪。
为何常见:PSI 输出格式中 each 资源各占一行,初学者容易把行首的 some/full 误当成不同的资源实体。
误区avg10 是最灵敏的,看它超过阈值就报警、就扩容,其他两个窗口无所谓。
正解avg10 灵敏但易波动,单靠它会产生大量误报。比如一次 GC 暂停或一个瞬时大请求就可能让 10 秒均值跳到 50%,实际 1 分钟后就恢复 5%。正确姿势是“三窗联看”:avg10 负责快速发现,avg60 负责确认趋势,avg300 负责评估基线。扩容决策至少以 avg10 超过阈值且 avg60 同步上行作为必要条件,才能过滤掉毛刺。
为何常见:人偏爱“最新鲜”的数字,avg10 在界面展示上最显眼,容易被赋予过高的决策权重。
误区内存压力大就是 swap 用的多,我看看 swap used 就知道了,何必看 PSI。
正解swap 使用率只是结果之一,内存 PSI 衡量的是“任务等待内存分配”的时长。即使 swap 没超限,内存碎片、页缓存回收抖动、NUMA 不平衡都会让任务在分配内存时被阻塞。更典型的是,内存压力 full 高企时系统几乎停滞,但 swap 可能只有几百 MB——因为任务的停滞发生在“等待可回收页”而不是“等待换页完成”。监控必须直接盯住任务等待时间,才能真正反映体感卡顿。
为何常见:swap 是内存压力的经典外在表征,运维习惯里“内存不够 → 看 swap”的路径依赖太强。
误区父 cgroup 的压力值 = 子 cgroup 压力值之和,所以总压力应该比任何子容器都大。
正解PSI 聚合在时间轴上做的是“并集合并”,而不是数值相加。如果容器 A 在 0-3 秒等待、容器 B 在 5-8 秒等待,父节点在 0-3 和 5-8 两个区间都记“有任务等待”,总时长为 6 秒而非 3+3=6 秒的简单累加(更不是 3×2)。因为并集只统计“是否存在等待”的布尔量,多个容器同时等待的区间不会重复计数。这保证了聚合后的压力值仍是 0-100 的百分比,语义上代表“这个子树里有没有任务在受饿”。
为何常见:直觉上“总和=各部分之和”,但忽视了 PSI 是一个基于时间占比而非事件次数的归一化指标。
面试题
Q1. PSI 中字母 P 的完整含义是什么?
- A.Process State Information
- B.Pressure Stall Information← 正确答案
- C.Performance Status Index
- D.Power Supply Indicator
答案:B。PSI 全称是 Pressure Stall Information,即“压力停滞信息”,核心是度量任务因资源竞争而停滞的时长。A 选项是进程状态,C/D 是干扰项,与内核资源压力的语义无关。
Q2. PSI 指标覆盖哪几类资源的压力统计?
- A.CPU← 正确答案
- B.磁盘 I/O← 正确答案
- C.内存← 正确答案
- D.网络带宽
答案:ABC。PSI 在 Linux 内核中通过 /proc/pressure/{cpu,memory,io} 三个文件分别统计 CPU、内存、磁盘 I/O 的压力。网络带宽尚未纳入 PSI 统计范围,因此 D 错误。
Q3. some 与 full 两种压力语义的本质区别是什么?
- A.some 只统计 CPU,full 只统计内存
- B.some 表示至少一个任务被阻塞,full 表示所有任务都被阻塞← 正确答案
- C.some 是平均值,full 是峰值
- D.some 与 full 是两套完全独立的采样系统
答案:B。some 记录“存在至少一个任务等待”的时长占比,full 记录“全部任务同时等待”的时长占比,两者是同一份阻塞事件在不同烈度下的统计口径。CPU 因为满员等待与空闲不可区分,不输出 full。B 正确描述了二者的语义。
Q4. PSI 中的 avg10、avg60、avg300 分别代表什么?
- A.过去 10/60/300 小时的累计平均值
- B.过去 10/60/300 秒的滑动加权平均值← 正确答案
- C.未来 10/60/300 秒的预测值
- D.系统启动以来 10/60/300 分钟的总压力
答案:B。avg10、avg60、avg300 是过去 10 秒、60 秒、300 秒三个滑动窗口的指数加权平均值。它们用于分别观察短期突变、中期趋势和长期基线,而非累计或预测值。
Q5. 关于 /proc/pressure/ 目录,下列说法正确的是?
- A.cpu 文件通常只包含 some 一行统计← 正确答案
- B.memory 文件同时包含 some 和 full 两行← 正确答案
- C.io 文件同时包含 some 和 full 两行← 正确答案
- D.net 文件提供网络带宽压力统计
答案:ABC。由于 CPU 满负荷等待与空闲无法区分,cpu 文件只有 some 行;memory 和 io 文件则同时输出 some 与 full。Linux 内核没有提供 /proc/pressure/net 网络压力文件,D 错误。
Q6. 为什么 CPU 压力只输出 some 而不输出 full?
- A.CPU 压力过高时内核会先崩溃,来不及统计 full
- B.单核视角下所有任务同时等 CPU 时,CPU 表现为空闲,与 idle 不可区分← 正确答案
- C.full 数据量超过存储上限被内核舍弃
- D.只有 ARM 架构支持 CPU 的 full 统计
答案:B。CPU 只有一个执行单元,当系统内所有任务都在等待 CPU 时,CPU 无指令可执行,这与系统处于 idle(空闲)状态在观测层面无法区分。因此内核无法可靠地统计 CPU 的 full 压力,只输出 some。这是 CPU 资源本身的物理特性决定的。
Q7. PSI 输出中的 total 字段含义是什么?
- A.参与统计的任务总数
- B.相应压力状态累计发生的总时长(微秒)← 正确答案
- C.cgroup 子节点的总数
- D.当前活跃线程数
答案:B。total 是某种压力状态自系统启动以来(或 cgroup 创建以来)累计发生的总时长,单位为微秒。它不受平均窗口影响,可用于计算更长时间范围的精确占比,或校验 avg 值的合理性。
Q8. cgroup 级 PSI 聚合在实际生产中的价值体现在哪些方面?
- A.支持按容器/租户精细监控资源饥饿← 正确答案
- B.帮助定位哪个业务分组造成了节点压力← 正确答案
- C.替代内核的原生调度器
- D.为单容器粒度的自动扩缩容提供信号← 正确答案
答案:ABD。cgroup 级 PSI 让监控粒度从节点下沉到容器或业务组,既能定位压力源头,也能为每个容器单独配置扩缩容策略。但它只是观测指标,不会也无法替代内核调度器,C 错误。
Q9. 基于 PSI 的自动扩缩容中,“冷却时间(防抖)”的主要作用是什么?
- A.降低 PSI 采样频率以节省 CPU
- B.防止系统在扩容与缩容之间频繁震荡← 正确答案
- C.让扩容后的实例有更长的启动时间
- D.强制所有扩容操作排队等待审批
答案:B。冷却时间要求两次扩缩容动作之间至少间隔 τ 分钟,避免“压力刚超阈值就扩容、实例刚就绪压力已回落又缩容”的循环震荡。它本质上是为了平滑决策,而不是降低采样频率或限制运维流程。
Q10. 与 load average 相比,PSI 指标最核心的差异化优势是什么?
- A.load 无法区分 CPU 与 I/O 各自造成的压力,PSI 分别统计三类资源← 正确答案
- B.load 只能看 5 分钟均值,PSI 提供秒级精度
- C.load 适用于单机,PSI 只能用于容器
- D.两者完全等价,PSI 只是新版本的 load
答案:A。load average 把可运行任务与不可中断任务混在一起计数,无法判断瓶颈在 CPU 还是 I/O;PSI 则按 CPU、内存、IO 分别统计等待时长,并区分 some/full 烈度,能够精准定位资源瓶颈。PSI 同样适用于单机全局统计,C 错误。