Skip to content

KVM 高级特性与性能调优

本章节介绍 KVM 的高级虚拟化特性,包括热迁移、CPU 亲和性、NUMA 优化、巨页内存,以及性能调优技术。


热迁移(Live Migration)

热迁移允许在虚拟机运行状态下将其迁移到另一台物理主机,实现零停机迁移和负载均衡。

前提条件

  • 两台或多台物理主机
  • 共享存储(NFS、iSCSI、Ceph 等)
  • 相同版本的 KVM/QEMU
  • 相同的 CPU 特性(或兼容)
  • 高速网络(建议 10Gb+)

配置共享存储

bash
# 在所有主机上挂载共享存储
mount -t nfs 192.168.1.100:/shared/vms /var/lib/libvirt/images

# 验证挂载
df -h | grep shared

执行热迁移

bash
# 基本热迁移命令
virsh migrate --live vm01 qemu+ssh://192.168.1.101/system

# 带参数的热迁移
virsh migrate --live \
    --unsafe \
    --compressed \
    --parallel \
    --parallel-type threads \
    --migrateuri tcp:192.168.1.101:49152 \
    vm01 qemu+ssh://192.168.1.101/system

# 迁移后保持运行
virsh migrate --live vm01 qemu+ssh://192.168.1.101/system --persistent

迁移参数说明

参数说明
--live启用实时迁移
--unsafe强制迁移(忽略安全检查)
--compressed启用压缩传输
--parallel并行迁移
--migrateuri指定迁移 URI
--persistent迁移后保持持久运行

监控迁移进度

bash
# 查看迁移状态
virsh migrate-get-speed vm01

# 设置最大迁移带宽(单位:MB/s)
virsh migrate-setspeed vm01 500

# 查看迁移进度(通过 VNC 或控制台)
# 在目标主机上查看
virsh list

迁移注意事项

  1. 共享存储:源和目标主机必须能访问同一存储
  2. 网络:确保虚拟机网络在目标主机上可用
  3. CPU 兼容性:目标主机 CPU 必须支持虚拟机的 CPU 特性
  4. 内存:确保目标主机有足够内存

CPU Pinning(CPU 亲和性)

CPU Pinning 将虚拟机的 vCPU 固定到物理 CPU 核心,减少上下文切换,提高性能。

查看 CPU 信息

bash
# 查看 CPU 核心分布
lscpu
# 输出示例:
# CPU(s): 16
# Thread(s) per core: 2
# Core(s) per socket: 8
# Socket(s): 1

# 查看 CPU 亲和性
taskset -pc $$

# 查看 NUMA 节点
numactl --hardware

配置 CPU Pinning

bash
# 方式一:通过 virsh 配置
virsh edit vm01

# 在 <vcpu> 部分添加 cputune:
<vcpu placement='static'>4</vcpu>
<cputune>
  <vcpupin vcpu='0' cpuset='0'/>
  <vcpupin vcpu='1' cpuset='1'/>
  <vcpupin vcpu='2' cpuset='2'/>
  <vcpupin vcpu='3' cpuset='3'/>
  <emulatorpin cpuset='0-3'/>
</cputune>

# 方式二:运行时动态配置
virsh vcpupin vm01 0 0
virsh vcpupin vm01 1 1
virsh vcpupin vm01 2 2
virsh vcpupin vm01 3 3

# 查看配置
virsh vcpupin vm01

CPU Pinning 策略

策略说明适用场景
专用核心为每个 vCPU 分配独立物理核心高性能计算、低延迟应用
共享核心多个 vCPU 共享物理核心通用工作负载
隔离核心预留核心给特定虚拟机实时应用、数据库

NUMA 亲和性

NUMA(Non-Uniform Memory Access)优化确保虚拟机内存分配在本地 NUMA 节点,减少内存访问延迟。

查看 NUMA 信息

bash
# 查看 NUMA 节点
numactl --hardware

# 查看内存分布
numactl --show

# 查看进程的 NUMA 亲和性
numactl --pid --show

配置 NUMA 亲和性

bash
# 在虚拟机 XML 中配置
virsh edit vm01

# 添加 numatune 配置:
<numatune>
  <memory mode='strict' nodeset='0-1'/>
</numatune>

# 或者自动分配
<numatune>
  <memory mode='preferred' nodeset='0'/>
</numatune>

# 查看当前配置
virsh numatune vm01

NUMA 模式说明

模式说明
strict必须在指定节点分配内存
preferred优先在指定节点,失败时允许其他节点
interleave跨节点交错分配

巨页内存(Huge Pages)

巨页内存减少 TLB(Translation Lookaside Buffer)miss,提高大内存工作负载性能。

配置巨页内存

bash
# 查看当前巨页配置
cat /proc/meminfo | grep Huge

# 启用透明巨页(THP)
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo always > /sys/kernel/mm/transparent_hugepage/shmem_enabled

# 预留巨页(2MB 大小)
# 方式一:临时设置
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

# 方式二:永久配置
echo "vm.nr_hugepages=1024" >> /etc/sysctl.conf
sysctl -p

# 验证巨页
cat /proc/meminfo | grep Huge

在虚拟机中使用巨页

bash
# 在虚拟机 XML 中配置
virsh edit vm01

# 添加 memory backing:
<memoryBacking>
  <hugepages/>
</memoryBacking>

# 或者指定巨页大小
<memoryBacking>
  <hugepages>
    <page size='1G' unit='G'/>
  </hugepages>
</memoryBacking>

巨页配置示例

bash
# 为大内存虚拟机配置 1GB 巨页
# 1. 预留 8 个 1GB 巨页
echo 8 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages

# 2. 配置虚拟机
virsh edit vm01
# 添加:
<memory unit='G'>64</memory>
<memoryBacking>
  <hugepages>
    <page size='1' unit='G'/>
  </hugepages>
</memoryBacking>

性能调优

VirtIO 驱动

VirtIO 是半虚拟化驱动,提供比模拟驱动更好的性能。

磁盘 VirtIO

bash
# 在虚拟机 XML 中配置
virsh edit vm01

# 将磁盘改为 virtio 总线:
<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/var/lib/libvirt/images/vm01.qcow2'/>
  <target dev='vda' bus='virtio'/>
</disk>

网络 VirtIO

xml
<interface type='network'>
  <source network='default'/>
  <model type='virtio'/>
</interface>

VirtIO 其他设备

xml
<!-- 串行控制台 -->
<console type='pty'>
  <target type='virtio' port='1'/>
</console>

<!-- 内存 balloon -->
<memballoon model='virtio'/>

<!-- 随机数生成器 -->
<rng model='virtio'>
  <backend model='random'>/dev/urandom</backend>
</rng>

VirtIO 配置对比

设备类型模拟驱动VirtIO 驱动性能提升
磁盘IDE/SCSIvirtio-blk2-3x
网络e1000/rtl8139virtio-net3-5x
控制台serialvirtio-serial2x

DPDK 加速

DPDK(Data Plane Development Kit)提供用户空间网络驱动,绕过内核,提供极高网络性能。

安装 DPDK

bash
# 安装 DPDK
yum install -y dpdk dpdk-devel

# 加载 UIO 模块
modprobe uio
modprobe igb_uio

# 绑定网卡到 DPDK
dpdk-devbind.py --bind=igb_uio 0000:01:00.0

配置 DPDK 网络

bash
# 在虚拟机中使用 DPDK
virsh edit vm01

# 添加 DPDK 设备:
<interface type='hostdev' managed='yes'>
  <source>
    <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
  </source>
</interface>

SR-IOV 直通

SR-IOV(Single Root I/O Virtualization)允许物理网卡虚拟成多个 VF(Virtual Function),实现硬件直通。

启用 SR-IOV

bash
# 检查网卡是否支持 SR-IOV
lspci | grep -i ethernet

# 查看网卡 VF 数量
cat /sys/class/net/eth0/device/sriov_totalvfs

# 创建 VF
echo 4 > /sys/class/net/eth0/device/sriov_numvfs

# 验证 VF
lspci | grep -i "Virtual Function"

配置 VF 直通

bash
# 将 VF 分配给虚拟机
virsh attach-interface vm01 hostdev 0000:01:10.1 --managed yes

# 或者在 XML 中配置
virsh edit vm01
<interface type='hostdev' managed='yes'>
  <source>
    <address type='pci' domain='0x0000' bus='0x01' slot='0x10' function='0x1'/>
  </source>
</interface>

其他性能优化

关闭 CPU 节能

bash
# 查看当前调度器
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 设置性能模式
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
    echo performance > $cpu
done

# 永久配置
echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

调整 I/O 调度器

bash
# 为 SSD 设置 noop 调度器
echo noop > /sys/block/sda/queue/scheduler

# 为机械盘设置 deadline 调度器
echo deadline > /sys/block/sda/queue/scheduler

启用 CPU 特性

bash
# 在虚拟机中启用高级 CPU 特性
virsh edit vm01

# 配置 CPU 模式:
<cpu mode='host-passthrough'/>
# 或者
<cpu mode='custom' match='exact'>
  <model fallback='allow'>Skylake-Client</model>
  <feature policy='require' name='ssbd'/>
  <feature policy='require' name='rdtscp'/>
</cpu>

常见问题

Q: 热迁移失败,提示 "migration failed: Unsafe migration"

原因:CPU 特性不兼容或共享存储问题。

解决方法

bash
# 使用 --unsafe 参数强制迁移
virsh migrate --live --unsafe vm01 qemu+ssh://target-host/system

# 或者配置 CPU 为 host-passthrough
virsh edit vm01
<cpu mode='host-passthrough'/>

Q: CPU Pinning 后虚拟机性能下降

原因:CPU 核心分配不合理,导致资源争用。

解决方法

bash
# 检查 CPU 使用情况
virsh vcpuinfo vm01

# 调整 Pinning 策略,确保每个 vCPU 有独立核心
# 或者使用 isolcpus 隔离核心

Q: 巨页内存分配失败

原因:系统内存不足或巨页大小不匹配。

解决方法

bash
# 检查可用巨页
cat /proc/meminfo | grep Huge

# 清理内存缓存
sync && echo 3 > /proc/sys/vm/drop_caches

# 重新分配巨页
echo 512 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

Q: VirtIO 驱动未安装

原因:虚拟机未安装 VirtIO 驱动。

解决方法

bash
# Windows 虚拟机:下载 VirtIO 驱动 ISO
# https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/

# Linux 虚拟机:通常已内置
# 检查驱动
lsmod | grep virtio

下一步

掌握高级特性后,继续学习 故障排查与企业实践 了解生产环境运维知识。