r 值表示运行队列长度,即正在运行或等待 CPU 调度的进程总数;若长期高于 CPU 核心数,说明调度拥堵,需结合 D 状态进程、iostat、中断统计、cgroup throttling 等多维度排查真实瓶颈。

看懂 r 值到底在等什么
r 是 vmstat 中「运行队列长度」,它统计的是**正在 CPU 上运行 + 等待 CPU 调度的进程总数**。注意:它不区分用户态/内核态,也不管进程是不是卡在 I/O、锁、内存分配或中断里——只要没被调度出去,就还在队列里。所以 r 长期高于 CPU 核心数(比如 8 核服务器 r > 8),说明调度器“排不上号”,但 top 里看不到高 CPU 进程,恰恰说明这些进程根本没机会跑满 CPU,而是被别的东西拦住了。
重点排查 D 状态进程和不可中断等待
当进程因磁盘 I/O、NFS 挂载、内核锁或硬件驱动阻塞时,会进入 D(Uninterruptible Sleep)状态。这类进程:
• 不响应信号(kill -9 无效)
• 不计入 top 的 CPU 使用率(因为没执行指令)
• 却持续占据 r 队列位置
• 在 ps aux 输出中 STATE 列显示为 D
- 快速检查:
ps -eo stat,pid,comm | grep "^D" - 结合
vmstat 1观察b列(阻塞进程数)是否同步升高;若r和b都高,基本锁定 I/O 或内核路径阻塞 - 用
iostat -x 1看%util是否接近 100%、await是否远超 10ms(SSD)或 50ms(HDD)
别漏掉中断和内核线程的“隐形消耗”
CPU 负载高但用户进程不占 CPU,常见于高频硬件中断(如网卡收包、NVMe 驱动、USB 设备)或内核线程密集争抢资源。这类负载不会出现在 top 默认视图,但会推高 vmstat 的 in(每秒中断数)、cs(上下文切换)和 sy(系统态 CPU)。
- 查中断分布:
watch -n1 'cat /proc/interrupts | sort -k2nr | head -10',关注某 CPU 上某设备中断是否突增 - 查内核线程:
top -H -p $(pgrep kthreadd)或ps -eLh o pid,tid,class,rtprio,ni,pri,psr,pcpu,state,comm | awk '$11=="R" || $11=="D" {print}' | sort -k7nr | head -10 - 确认 irqbalance 是否启用:
systemctl is-active irqbalance;若关闭且中断集中在一个核,r高就非常典型
短生命周期进程和 cgroup 限制也会“藏”负载
频繁 fork/exit 的进程(如 CGI 脚本、容器健康检查、日志轮转)可能在 top 刷新间隔(默认 3 秒)内一闪而过,导致“看不见但压得死”。另外,如果进程受 cgroup CPU quota 限制(如 cpu.max = 10000 100000),它会反复被 throttled,表现为调度队列积压,但单次运行时间极短,top 统计不到显著占用。
- 捕获瞬时进程:
pidstat -u 1 10(比top更细粒度)或atop -r /var/log/atop/atop_$(date +%Y%m%d) -r 1(需提前开启 atop 日志) - 检查 cgroup 限频:
cat /sys/fs/cgroup/cpu,cpuacct/*/cpu.stat 2>/dev/null | grep throttled,有非零值即存在节流 - 验证是否是调度延迟本身:
perf sched latency -s max可输出最高调度延迟及对应进程
真正难缠的不是 r 高,而是它背后混着 I/O 阻塞、中断风暴、内核锁竞争、cgroup 节流等多种机制——必须靠 vmstat 定向、ps/iostat/perf 多点交叉,才能揪出那个“不动声色却堵死通道”的元凶。










