本文主要介绍 KVM 虚拟机 CPU 绑定在 Libvirt/CGroup 中的实现思路、常用查看与配置方式,并整理一份用 UnixBench 做性能对照时的历史跑分摘要。原稿以读书笔记与跑分日志为主,完整的“动态热绑定”生产编排流程仍有待补全

Libvirt 对虚拟机资源限制多建立在 Linux CGroup 之上:CPU 集合、配额、磁盘与网络 IO 等都可通过 CGroup 控制器约束进程组。直接对 QEMU 进程写 CGroup 可以生效,日常更推荐通过 Libvirt XML / virsh 管理,便于与域生命周期一致。

背景说明

CPU 绑定(pinning)的常见目的:

  • 降低跨 NUMA 节点访问,稳定时延
  • 避免与宿主机关键中断/其他 VM 抢核
  • 做性能对比实验时固定算力边界

绑定对象通常是 vCPU 线程与宿主机逻辑 CPU(有时还要区分 sibling / 隔离 CPU)。是否“动态”取决于是否在虚拟机运行中改 pin;Libvirt 支持运行时 vcpupin,但生产变更仍要评估缓存亲和与业务抖动。

环境信息

项目说明
虚拟化KVM + Libvirt(版本待确认)
基准工具UnixBench 5.1.x
对照样本笔记本 WSL2 环境 vs 机房 KVM 客户机(历史 2020-09 记录)

具体宿主机型号、是否 CPU isolation(isolcpus 等)以现场为准。

核心概念

CGroup 与 Libvirt

CGroup 按层级对进程组做资源限制与记账。虚拟机的 QEMU 进程及其 vCPU 线程可被放入特定 cpuset,从而只在允许的 CPU 上调度。Libvirt 在域 XML 中暴露 cputune 等配置,并在启动/热更新时落到 CGroup。

查看 vCPU 与物理 CPU 对应关系

virsh vcpuinfo <domain>

输出中通常包含每个 vCPU 的编号、是否 online、以及当前 CPU Affinity。若尚未 pin,亲和可能覆盖较多逻辑 CPU;pin 成功后应收敛到目标集合。

也可查看:

virsh vcpupin <domain>

用于列出当前 pin 映射(无参数时)或设置映射(带 vCPU 号与 CPU 列表时,以 virsh help vcpupin 为准)。

配置方式

运行时 pin(示例)

将域 <domain> 的 vCPU 0 绑到宿主机 CPU 2(示例,勿照抄编号):

virsh vcpupin <domain> 0 2
virsh vcpuinfo <domain>

多 vCPU 时按拓扑逐个设置,或使用 XML 一次性声明。判断标准:vcpuinfo / vcpupin 显示的亲和与预期一致,且业务线程未再跑到未授权 CPU(可用 taskset/htop 在宿主机侧核对 QEMU 线程,具体 PID 因环境而异)。

域 XML 中的 cputune(示例)

<cputune>
  <vcpupin vcpu='0' cpuset='2'/>
  <vcpupin vcpu='1' cpuset='3'/>
  <!-- 视需要添加 emulatorpin、iothreadpin、vcpusched 等 -->
</cputune>

修改持久化 XML 后,按是否热更新选择 virsh define + 重启域,或使用支持的 live 更新路径。错误的 cpuset(超范围、与 host 拓扑冲突)可能导致启动失败或性能反噬。

与 NUMA、emulator 线程

仅 pin vCPU 有时不够:emulator、iothread 仍可能漂到其它核。完整方案常同时配置 emulatorpin / iothreadpin,并与 numatune 对齐。本篇不做展开,按宿主机 numactl -H 与业务时延目标单独设计。

用 UnixBench 做对照

UnixBench 适合做同环境变更前后粗粒度平台差异对照,不适合单独作为上线 SLA 依据。跑分受频率、睿频、后台负载、WSL 虚拟化层影响很大。

历史样本摘要

下列 Index Score 摘自原稿完整日志(UnixBench 5.1.3),仅作数量级参考:

环境(脱敏描述)CPU 概要并行度System Benchmarks Index Score
笔记本 WSL2 + CentOS 8 用户态Ryzen 7 4800H,16 逻辑 CPU1 copy约 1830
同上同上16 copies约 8282
机房 KVM 客户机Xeon E5-2640 v2,客户机 8 vCPU1 copy约 1081~1097
同上同上8 copies约 4463~4502

说明:

  • WSL2 与裸金属/KVM 不可直接横比绝对分,虚拟化路径与内核不同。
  • 客户机两次 8 并行跑分接近,说明该负载下结果可重复性尚可。
  • 原稿未给出“绑定前 vs 绑定后”同机对照;若要验证 pin 收益,应在同一 KVM 域、固定负载下改 pin 再跑,并记录 vcpupin 状态。

跑分注意

# 在目标环境安装/编译 UnixBench 后执行(路径以现场为准)
./Run
  • 跑分期间尽量静置宿主机与其它 VM
  • 记录 virsh vcpupin、是否限频、是否同 NUMA
  • 保留完整 log 时注意脱敏主机名

验证结果

CPU 绑定是否生效,建议同时满足:

  1. virsh vcpupin <domain> 与 XML 一致
  2. virsh vcpuinfo <domain> 中亲和正确
  3. 业务或基准在变更前后有可解释的差异(无差异也要记录,避免假阳性)

注意事项

  • 过度绑定可能导致某个物理核过热/过载,而其它核空闲;要结合监控看 %steal、CPU 利用率与尾时延。
  • 宿主机更新内核、迁移 VM、改 CPU 拓扑后,原 cpuset 可能失效,需要重做。
  • 原稿含大段 UnixBench 原文输出与书籍章节引用,本文已收敛为可维护摘要;动态编排(例如按负载自动改 pin)不在现有材料范围内,标为待后续补写。
  • 不要从互联网或记忆编造具体 vcpuinfo 表格输出;以本机命令为准。

参考资料