CPU steal 时间(st)持续偏高但宿主机负载正常的虚拟化层排查

9次阅读

CPU steal时间偏高而宿主机负载正常,表明问题在虚拟化层调度或配置:需检查cgroups CPU限频、vCPU与NUMA节点绑定错配、嵌套虚拟化及内核调度参数等。

CPU steal 时间(st)持续偏高但宿主机负载正常的虚拟化层排查

CPU steal 时间(st)持续偏高,而宿主机整体 CPU 负载正常,说明虚拟机在等待 CPU 调度的时间变长,但物理 CPU 并未饱和——问题大概率出在虚拟化层的资源调度或配置上,而非宿主机过载。

检查虚拟机 CPU 配额与限制设置

过度限制 vCPU 的 CPU 时间配额(如 cpu.cfs_quota_us / cpu.cfs_period_us),会导致虚拟机频繁被 throttled,表现为 st 升高。KVM/QEMU 中常见于使用 cgroups v1 限频、或 libvirt 的 + 组合配置不当。

  • 在宿主机上运行 cat /sys/fs/cgroup/cpu/libvirt/qemu//cpu.stat,查看 nr_throttledthrottled_time 是否非零且持续增长
  • 检查 libvirt xmlvirsh dumpxml | grep -A5 "",确认是否设置了
  • 临时移除 CPU 限频测试:virsh schedinfo 查看当前值,用 virsh schedinfo --set cpu_quota=-1 取消限制后观察 st 是否回落

排查 vCPU 绑定与 NUMA 拓扑错配

vCPU 被绑定到远离内存节点的物理 CPU 核心(例如跨 NUMA node 调度),会加剧调度延迟和 steal 时间,尤其在内存密集型负载下。

  • virsh vcpuinfo 查看 vCPU 当前运行的 pCPU ID
  • 对比 numactl --hardware 输出,确认该 pCPU 所属 NUMA node 与虚拟机内存分配的 node 是否一致(virsh dumpxml | grep -A5 ""
  • 若不匹配,修改 XML 中 设置,显式指定 并启用 对齐,或改用 自动对齐

确认宿主机调度器与 KVM 参数合理性

某些内核调度策略或 KVM 启用方式会放大 steal 时间统计偏差,尤其在高密度虚拟化场景中。

  • 检查是否启用了 kvm-intel.nested=1kvm-amd.nested=1:嵌套虚拟化会增加调度开销,非必要时建议关闭
  • 确认宿主机内核未启用 NO_HZ_FULL(全动态滴答)模式:该模式在 vCPU 空闲时可能干扰 steal 时间计算,可通过 cat /boot/config-$(uname -r) | grep CONFIG_NO_HZ_FULL 验证
  • 检查 QEMU 进程是否以 -cpu ...,kvmclock=on 启动(libvirt 默认开启),确保 guest 内核能正确感知 steal 时间;若 guest 使用老内核(kvmclock 模块

排除 hypervisor 层争用与中断瓶颈

即使宿主机平均负载低,局部资源争用(如单个物理 CPU 核心过载、硬中断集中、或 KVM ioctl 频繁调用)也会导致特定 vCPU 被长期“steal”。

  • pidstat -t -p $(pgrep -f "qemu.*") 1 观察 QEMU 主线程(TID)及 vCPU 线程(通常含 “CPU…” 字样)的 %usr/%sys 分布,若某 vCPU 线程 %sys 异常高,可能卡在内核态(如锁竞争或中断处理)
  • 运行 perf top -p $(pgrep -f "qemu.*"),关注 kvm_vcpu_ioctl__hrtimer_run_queuesnative_queued_spin_lock_slowpath 等热点函数
  • 检查硬中断分布:cat /proc/interrupts | grep -E "(eth|nvme|ioat)",确认网卡/存储中断是否集中在某几个 CPU 上,可配合 irqbalance 或手动绑核缓解
text=ZqhQzanResources