OpenStack虚拟机CPU性能优化与监控,核心思路就两条:宿主机层面做好NUMA感知和CPU绑定,虚拟机内部做好中断和频率调优;监控层面则紧盯CPU steal time和vCPU ready time两个关键指标。
OpenStack虚拟机CPU性能优化,为什么要先管宿主机调度?
绝大多数OpenStack部署中,虚拟机CPU卡顿的根源不在Guest内部,而是宿主机把vCPU线程随意调度到了错误的物理核心上,默认情况下,Libvirt和内核调度器只保证vCPU线程可运行,不保证它“住得近、跑得快”,这会导致两个问题:一是跨NUMA节点访问内存,延迟成倍上升;二是多个vCPU线程争抢同一个物理超线程,互相拖累。
NUMA拓扑绑定:让vCPU跑在物理CPU身边
现代服务器少则两颗CPU,多则八颗,每颗CPU配一组本地内存,这就是NUMA节点,虚拟机如果只被分配到一个节点内的CPU和内存,性能最稳;一旦跨节点,内存访问要走跨片总线,数据库和高负载服务的响应时间会明显变长。
在OpenStack里,通过flavor定义NUMA亲和最简单,管理员可以先在计算节点上执行lscpu确认拓扑,然后为性能敏感型虚机机定义专属flavor:
hw:numa_nodes=1:强制虚拟机的所有vCPU和内存在同一个NUMA node上。hw:numa_mempolicy=preferred:尽量优先使用本地内存,不够再跨节点。hw:cpu_policy=dedicated:不做CPU超配,每个vCPU独占一个物理核心。hw:cpu_thread_policy=isolate:避免vCPU使用同一个物理核的两个超线程。
云平台用户选择该flavor创建虚机后,可以在计算节点上执行virsh vcpuinfo <实例名>,查看每个vCPU线程实际跑在哪个物理CPU上,符合预期则说明NUMA绑定生效,这也算一种快速验证手段。
CPU pinning vs 超配:性能与密度的取舍
行业共识认为,CPU超配是云平台管理资源密度的手段,但超配比例越高,CPU steal time就越大,对于延迟敏感的在线业务,比如Redis、Nginx网关、金融交易系统,建议关闭超配,直接使用CPU pinning。
CPU pinning操作在OpenStack中很简洁,不需要逐台虚拟机手工配置,管理员可以为特定flavor设置hw:cpu_policy=dedicated,再让虚机绑定到指定CPU集合,如果想对已有实例做调整,也可以登录计算节点,用virsh vcpupin动态修改,但该操作在虚机热迁移后会失效,只适合应急。
另一种折中方案是reserved_host_cpus,在nova.conf中预留一部分物理CPU给宿主机自身的QEMU进程和保护性余量,避免vCPU线程与虚拟化引擎争抢,例如一台物理机有32个物理线程,可以预留2个给宿主机,剩余30个参与虚拟机调度,凡是CPU密集型的NoSQL、搜索节点,都建议按这个思路规划。
虚拟机内部CPU优化:超线程、中断与内核参数
宿主机调度之外,虚拟机操作系统本身也有很多可调空间,很多人容易忽略一点:即便宿主机已经绑定了CPU,Guest内部若不做中断隔离,网卡和磁盘的中断处理依然会抢占vCPU时间片。
openstack虚拟机cpu性能差怎么办?先检查超线程和内核tick
遇到虚机CPU性能差,第一件事不是改内核参数,而是确认vCPU之间是否在抢超线程,用virt-manager图形界面打开虚机详情,查看vCPU的“CPU拓扑”列表,如果两个vCPU的“Physical CPU number”相同且“Sibling number”不同,说明它们共享同一个物理核。
这种情况的处理路径有两种:要么在flavor中增加hw:cpu_thread_policy=require,迫使每个vCPU使用独立的完整物理核;要么在Guest内关闭SMT相关调度,例如Linux下把siblings中的CPU全部隔离出cpuset,但后一种方式浪费资源,更推荐前者。
另一个常见性能瓶颈是内核定时器抢占,CentOS和Ubuntu默认的CONFIG_HZ分别为1000和250,虚机空转时大量CPU时间花在处理tick中断上,可以在虚机内设置启动参数processor.max_cstate=1 intel_idle.max_cstate=0,并开启nohz_full,把时间尽量留给用户态业务,对RocksDB、ClickHouse这类自旋锁多的程序,这个改动往往能带来直观的延迟下降。
中断绑定与vCPU线程优先级
当虚机网络流量很大时,多队列网卡的每个队列都会发中断,这些中断如果落在运行vCPU线程的物理核上,就会反复抢占vCPU,经验做法是:把宿主机上的网络中断绑定到空闲物理核,再把vCPU线程设为SCHED_FIFO实时优先级。
具体到OpenStack场景中,操作分两步,首先在计算节点上执行echo 0000:af > /proc/irq/143/smp_affinity,将特定网卡中断的亲和性指定到非vCPU所用的CPU集合,然后通过virsh schedinfo --live --set vcpu_period=100000 --set vcpu_quota=100000 <实例名>,为vCPU线程提供一个接近实时的调度预算,注意,这个值要小于100000才能限制CPU,等于100000表示不限制,对极少数延迟关键型业务,可以临时将
vcpu_quota设为最大值,但生产环境不建议长期这样跑,因为会饿死其他普通虚拟机。
OpenStack虚拟机CPU性能监控怎么做?从命令到平台
优化做得再好,不监控等于盲开,监控的目的不是事后看报表,而是实时发现“vCPU线程被偷走了多少时间”。
用virsh和qemu直接看vCPU线程
首先给出三个高频命令,任何做过OpenStack维护的人应该都不陌生:
virsh vcpuinfo <实例名>:逐一列出每个vCPU的CPU亲和性、运行时长、当前运行的物理CPU。virsh domstats --cpu-total <实例名>:输出vCPU的总时间,包括busy time和steal time。virsh qemu-monitor-command --pretty <实例名> --cmd "info cpus":查看QEMU层面各vCPU线程的实时状态。
在domstats输出里,重点看vcpu.<n>.time和vcpu.<n>.wait,其中wait值高,意味着vCPU线程在宿主机调度队列里等待但没有获得物理CPU,基本等同于CPU饥饿,如果这个值持续上涨,而虚机业务又不算繁忙,多半是超配过度宿主机背不住,或者有别的虚机在抢跑。
监控平台指标:CPU steal与ready time
当你管理几十台物理机时,不可能每台都手工敲命令,行业通用做法是接入Prometheus + libvirt_exporter,或者用Ceilometer采集nova-compute上报的CPU使用率。
更精细的指标有两个:CPU steal percentage和vCPU ready time,前者是Guest从自己的视角统计“被宿主机偷走”的CPU时间占比,后者是宿主机上vCPU线程等待调度的累计时间,两者有细微差别,但都指向同一个问题:宿主机CPU资源不够或者调度不均。
平台告警建议分层设置:
- CPU steal > 5%且持续10分钟:提示超配可能过载,需要排查同节点的其他虚机。
- CPU steal > 15%且持续30分钟:应考虑迁移该虚机或降低宿主机的运行虚机数。
- vCPU ready time超过vCPU总时间的30%:基本可以判定虚拟机的CPU配置不达标,业务高峰期会明显卡顿。
不要只看宿主机整体CPU使用率,一个物理机CPU平均50%,某个NUMA节点可能已经满载,所以理想的监控面板上,应当以NUMA节点为单位绘制CPU使用率和steal time热力图,这个做法在大型OpenStack私有云里已经比较常见,能提前暴露调度热点,而不是等到应用报警才去排查。
OpenStack虚拟机CPU性能调优方案中容易踩的坑
最后不得不提几个反模式,有人为了追求性能,把宿主机上所有CPU都分配给虚拟机,还设置vCPU线程实时优先级,结果宿主机的migration进程和kvm管理线程被饿死,反而导致虚机CPU状态卡住,正确做法是始终保留一部分宿主机CPU给管理面和IO线程,即使物理机资源紧张,也不要低于两颗逻辑CPU。
另一个坑是在虚机内盲目关闭irqbalance服务,对单队列网卡来说,关闭irqbalance手动绑定中断可能有效,但在多队列网卡和复杂NUMA环境下,手动配置容易让中断集中到一个核心上,更稳妥的方式是让宿主机的irqbalance使用smp_affinity限制,而不是完全禁用。
从实践反馈来看,OpenStack虚拟机CPU性能优化是一个从flavor设计、宿主机配置、Guest内核参数到监控告警的完整链条,只调一段往往治标不治本,真正的线上问题,多数是CPU steal偏高和NUMA跨节点访问共同造成的,需要在部署阶段就规划好计算节点的CPU拓扑,而不是等业务受损后再做补偿。
OpenStack虚拟机CPU监控与优化Q&A
如何判断当前虚拟机是否发生了CPU steal?
在虚拟机内部执行top,查看%st列,该值表示CPU时间被宿主机抢占的比例,长时间大于5%,同时业务响应变慢,就说明宿主机CPU超配过重,或者登录计算节点执行virsh domstats --cpu-total <实例名>,观察wait时间是否持续增加。
CPU绑定后虚拟机还能热迁移吗?
可以,但前提是目标宿主机有相同的物理CPU拓扑和足够数量的空闲核心,OpenStack的libvirt驱动会在热迁移时检查CPU映射是否符合要求,如果目标机器拓扑不同,迁移会失败,建议对绑定CPU的虚机关闭自动迁移,或者迁移前手动确认目标宿主机。
超线程对虚拟机CPU性能有多大影响?
同一物理核上的两个逻辑线程共用执行单元,当一个vCPU占用该物理核进行高密度计算时,另一个vCPU的性能会明显下降,下降幅度可达20%到40%,对于计算密集型虚机,建议使用hw:cpu_thread_policy=isolate确保每个vCPU独占完整物理核,而不是共享超线程。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/619245.html





