cpu偷取率(%steal)是虚拟机被宿主机调度器强制让出cpu时间的比例,反映底层资源争抢程度;vstats能看但默认不显示,因其专为虚拟化设计且需手动编译安装,而top、vmstat等传统工具未集成该字段。

什么是CPU偷取率,为什么vstats能看但默认不显示
CPU偷取率(%steal)是虚拟机被宿主机调度器强制让出CPU时间的比例,反映底层资源争抢程度。Linux内核从2.6.11起就在/proc/stat中提供steal字段,但传统工具如top、vmstat默认不展示它。而vstats是专为虚拟化环境设计的轻量监控工具,它会主动解析/proc/stat并计算每秒变化率——但它本身不自带,需手动编译或从特定仓库获取,不是发行版默认包。
如何确认系统已安装可用的vstats
多数主流Linux发行版仓库不含vstats,它常随KVM/QEMU生态配套工具集发布,比如某些OpenStack节点镜像或RHEL/CentOS的virt-top相关源。运行以下命令验证:
which vstats
若返回空,说明未安装。此时不要用apt install vstats或yum install vstats——这些会失败。正确做法是:
- 检查是否已有
virt-top:它和vstats同源,部分版本附带vstats二进制; - 从
https://github.com/libvirt/libvirt/tree/master/tools拉取源码,用make vstats单独编译; - 确保编译时链接了
libvirt和libxml2,否则运行时报symbol lookup error: undefined symbol: virConnectGetLibVersion; - 静态编译可规避依赖问题,但需加
make LDFLAGS="-static",且宿主机glibc版本不能低于目标环境。
vstats输出里哪一列对应CPU偷取率
执行vstats -d 1(每秒刷新)后,输出共7列:TIME DOMAIN %CPU %MEM VCPU %STEAL IO_WA。其中%STEAL就是CPU偷取率,单位是百分比,值持续高于5%通常意味着宿主机过载或该VM被频繁节流。
注意两点:
-
%STEAL是**单vCPU维度**统计,不是整个VM汇总——一个4 vCPU的VM可能有1个vCPU偷取率12%,其余为0; - 该值基于两次
/proc/stat采样差值计算,若vstats进程被调度延迟(如宿主机负载极高),会导致数值跳变甚至负值,此时应结合cat /proc/stat | grep ^cpu手动比对steal字段验证; - 在容器化环境(如LXC)或非libvirt管理的QEMU实例中,
vstats可能无法识别domain,%STEAL列全为-,这时得回退到mpstat -P ALL 1查%steal字段。
长期采集%STEAL数据时容易忽略的陷阱
用vstats -d 1 >> steal.log记录日志看似简单,但实际部署中三个点常被跳过:
- 输出无时间戳(仅
TIME列是相对启动秒数),跨天分析时无法对齐其他监控系统,建议改用stdbuf -oL vstats -d 1 | while IFS= read -r line; do echo "$(date '+%Y-%m-%d %H:%M:%S') $line"; done >> steal.log; -
vstats默认只监控当前libvirt连接下的active domain,若VM中途启停,新启动的VM不会自动加入监控流,需重启vstats或改用--all参数(部分版本支持); - 高频率采样(如
-d 0.1)会显著增加libvirt daemon压力,在数百VM规模下可能触发libvirtd响应超时,表现为vstats卡住或报Connection reset by peer,稳妥做法是最低设为-d 2,再用插值补点。
真正棘手的是偷取率低但业务延迟高的情况——那往往不是CPU问题,而是磁盘I/O或网络中断被抢占,%STEAL看不出这些,得同步看/proc/interrupts里KVM相关中断分布和perf record -e kvm:kvm_exit事件。











