KVM vCPU
KVM vCPU 是虚拟机的虚拟处理器本质是QEMU 进程下的 Linux 线程由 KVM 内核模块 硬件虚拟化VT-x/AMD-V驱动通过 VM-Exit/VM-Entry 与 Linux 调度器实现高效虚拟化。一个 vCPU 宿主机上的一个普通 Linux 用户态线程 KVM 内核态虚拟化上下文结构上三层套娃从外到内QEMU 主进程管理虚拟机整机vCPU 线程qemu-system-x86_64下的CPU n/KVM线程就是普通pthread和你写 C 开的线程没有本质区别KVM vCPU 上下文内核里的struct kvm_vcpu硬件中的 VMCS/VMCB保存虚拟机寄存器状态QEMU vCPU Linux 用户态线程 KVM 内核虚拟化上下文 硬件虚拟化执行单元它不是虚拟出来的 “假 CPU”而是宿主机把一个物理 CPU 时间片以虚拟化模式租给虚拟机用。核心本质与架构vCPU Linux 线程每个 VM 对应一个 QEMU 进程每个 vCPU 是该进程的一个线程由 Linux CFS 调度器调度到物理 CPUpCPU / 逻辑核。KVMQEMU 分工KVM 内核模块kvm.ko、kvm-intel/amd.ko负责 CPU / 内存虚拟化提供/dev/kvm接口管理 VMCS、VM-Exit/VM-Entry。QEMU用户态设备模拟、VM 生命周期管理通过 ioctl 与 KVM 交互。硬件依赖必须开启 Intel VT-x 或 AMD-VCPU 在 ** 根模式Root宿主机 / KVM与非根模式Non-RootGuest** 间切换。运行本质宿主机直接在物理 CPU 上跑 Guest 代码QEMU vCPU 线程被 Linux 调度到一个物理核心上运行时执行KVM_RUNioctl进入VM-EntryCPU 切到Non-root 模式直接在硬件上执行虚拟机指令只有触发 VM-Exit 时I/O、敏感指令、中断才切回 QEMU/KVM 处理。所以vCPU 线程运行时 虚拟机在跑vCPU 线程被宿主机挂起 虚拟机被暂停和普通 Linux 线程的区别它本质就是普通线程只多了两点调用了 KVM 的 ioctl绑定了struct kvm_vcpu会进入硬件虚拟化的 Non-root 模式执行 Guest 代码调度、优先级、亲和性、阻塞、唤醒……完全遵守 Linux 调度器规则。vCPU 执行流程核心循环创建 vCPUQEMU 通过KVM_CREATE_VCPUioctl 创建 vCPU分配 VMCS虚拟机控制结构保存寄存器 / 状态。进入 Guest调用KVM_RUN执行VM-Entry进入非根模式Guest 代码直接在硬件上运行。VM-Exit 触发Guest 执行敏感指令如 IN/OUT、CR 寄存器访问、中断、异常或时间片到硬件自动触发 VM-Exit切回根模式。KVM 处理退出解析退出原因如 I/O、MMIO、中断必要时交由 QEMU 模拟设备。返回 Guest处理完成后执行VM-Entry恢复 vCPU 上下文继续执行。vCPU 与物理 CPUpCPU关系映射方式默认时分复用vCPU 总数可超 pCPU超分 / Overcommit可通过CPU Pinning绑定 vCPU 到指定 pCPU减少切换开销。NUMA 感知支持从指定 NUMA 节点分配 vCPU 与内存避免跨节点访问延迟。超线程物理核的超线程逻辑处理器可作为 pCPU 池vCPU 可调度到其上。超分比例vCPU 超分 所有虚拟机 vCPU 总数 ÷ 宿主机物理逻辑核数pCPU业务类型推荐超分比说明计算密集型数据库、大数据、压测、编译1:1 ~ 1:1.2基本不超分避免 CPU steal 飙升通用业务Web、API、微服务、中间件1:2 ~ 1:3最常用性能与密度平衡IO 密集 / 空闲型网关、日志、办公桌面、测试机1:4 ~ 1:6可高密度超分极端密度场景云桌面、弱业务容器化虚机1:6 ~ 1:8需严格监控不适合核心业务简单记重要业务不超分或轻微超分普通业务1:2~1:3闲置 / 轻量1:4~1:6怎么判断自己能不能超分看两个关键指标宿主机 CPU 平均利用率长期 50%可以继续加超分长期 70%不建议再超虚拟机 CPU steal 占用steal 3%正常3% ~ 5%轻微影响 5%超分过高必须降配 10%业务明显卡顿、时延飙升查看命令# 宿主机看整体 top # 虚拟机内部看 steal top # 看 %st 列 sar -u 1 10 # libvirt 看虚机 CPU 统计 virsh cpu-stats 虚拟机名超分常见坑同一时刻大量虚机同时跑满 CPU超分是靠 “错峰”如果所有 VM 同时压 CPU1:2 都会卡死。vCPU 数 物理 NUMA 节点核心数跨节点调度 跨节点访存性能会雪崩。Windows 虚机超分过高Windows 内核调度对 vCPU 抖动更敏感建议比 Linux 保守。安全上限建议生产线上保守线1:3有监控、可弹性扩容1:4超过 1:5 只适合非核心、可容忍卡顿的业务关键配置与优化libvirt XML 示例domain typekvm vcpu placementstatic4/vcpu !-- 分配4个vCPU -- cpu modehost-passthrough checknone/ !-- 透传CPU特性性能最优 -- cputune vcpupin vcpu0 cpuset0/ !-- vCPU0绑定pCPU0 -- vcpupin vcpu1 cpuset1/ vcpupin vcpu2 cpuset2/ vcpupin vcpu3 cpuset3/ emulatorpin cpuset4-5/ !-- QEMU emulator线程绑定pCPU4-5 -- /cputune numatune memory modestrict nodeset0/ !-- 内存绑定NUMA节点0 -- memnode cellid0 modestrict nodeset0/ /numatune /domainCPU 模式host-passthrough完全透传宿主 CPU 特性性能最佳适合同构集群。host-model复制宿主 CPU 模型兼容性好适合异构环境。custom手动指定 CPU 特性灵活但复杂。性能与调度要点明确原则计算密集型业务数据库、编译、压测尽量1:1 不超配vCPU 数 ≤ 物理 CPU 逻辑核数。IO 密集 / 普通业务可适度超配1:1.5 ~ 1:3。延迟敏感业务必须做 vCPU 绑定 宿主机 CPU 隔离。关键要点超分比例非 CPU 密集型场景可 1:2–1:4 超分数据库 / 计算密集型建议 1:1 或不超分。调度优化开启isolcpus隔离专用 pCPU 给 vCPU减少宿主机干扰。调整sysctl_sched_min_granularity、sysctl_sched_migration_cost减少 vCPU 切换开销。使用 ** 实时调度FIFO/RR** 绑定关键 vCPU降低延迟。中断亲和将网卡 / 存储中断绑定到非 vCPU 的 pCPU避免竞争。vCPU 绑定CPU Pinning1. 隔离宿主机专用 CPU在/etc/default/grub中给内核加参数isolcpus2-15 nohz_full2-15 rcu_nocbs2-15 tuned_nohz_full1isolcpus2-15这些 CPU 只给虚拟机用宿主机不调度普通进程。然后更新 grub 并重启grub2-mkconfig -o /boot/grub2/grub.cfg reboot2. 虚拟机 XML 绑定 vCPUvcpu placementstatic8/vcpu cputune vcpupin vcpu0 cpuset2/ vcpupin vcpu1 cpuset3/ vcpupin vcpu2 cpuset4/ vcpupin vcpu3 cpuset5/ vcpupin vcpu4 cpuset6/ vcpupin vcpu5 cpuset7/ vcpupin vcpu6 cpuset8/ vcpupin vcpu7 cpuset9/ !-- emulator 单独绑避免抢 vCPU -- emulatorpin cpuset10-11/ /cputuneCPU 模式直接透传性能提升最明显cpu modehost-passthrough checknone topology sockets1 cores8 threads1/ /cpuhost-passthrough虚拟机看到的 CPU 特性和物理完全一致AVX、RDTSC 等全部开放。不要用默认qemu64性能差很多。拓扑建议尽量sockets1多 sockets 会影响 NUMA 亲和。线程数设 1避免虚拟机内部超线程混乱。减少 VM-Exit核心优化1. 开启 APICv / VPIDIntelCPU 支持默认会自动开可在 XML 加features apic eoion/ vpid stateon/ /features2. 关闭不必要的时钟干扰clock offsetutc timer namehpet presentno/ timer namepit presentno/ timer namertc tickpolicycatchup/ timer namekvmclock presentyes/ /clock用kvmclock减少时钟导致的 VM-Exit。3. 开启 MWAIT / 暂停优化cpu modehost-passthrough checknone feature policyrequire namemonitor/ feature policyrequire namemwait/ /cpu让 vCPU idle 时更少触发 VM-Exit。NUMA 优化多路 CPU 必做1. 查看物理 NUMAnumactl -H2. 虚拟机内存与 vCPU 绑同一个 NUMA 节点numatune memory modestrict nodeset0/ /numatune cpu numa cell id0 cpus0-7 memory16777216 unitKiB memAccessshared/ /numa /cpu避免跨 NUMA 访问延迟可降低 30%。宿主机调度器优化# 降低调度切换频率 sysctl -w kernel.sched_migration_cost_ns5000000 sysctl -w kernel.sched_min_granularity_ns10000000 # 关闭透明大页碎片可选数据库建议关闭 echo never /sys/kernel/mm/transparent_hugepage/defrag使用 tuned 性能模式tuned-adm profile cpu-partitioningvCPU 状态与监控常用命令# 查看vCPU线程与pCPU绑定 ps -T -p qemu-pid # 监控vCPU调度与退出 perf stat -e kvm:kvm_entry,kvm:kvm_exit -p qemu-pid # libvirt查看vCPU信息 virsh vcpuinfo vm-name virsh cpu-stats vm-name关键指标VM-Exit 次数越少越好、vCPU 就绪时间、物理 CPU 利用率。