Akemi

Linux虚拟化调优

2025/06/04

rhel中,tuned提供了两个默认配置文件virtual-host和virtual-guest

RHEL默认启用自动NUMA均衡功能。该特性允许进程自动放置NUMA和定期取消内存映射,这将导致迁移到不同的NUMA节点,从而增加NUMA故障。

正常推荐手动NUMA放置覆盖自动NUMA平衡。

建议将客户机内存大小限制为单个NUMA节点上的物理内存量,以防止在NUMA节点之间分配资源

这里介绍

  • cpu调优
  • 内存调优
  • IO调优

网络调优比较复杂,不介绍

虚拟机cpu调优

虚机的虚拟CPU在宿主机上作为用户空间进程运行,可以使虚拟CPU进程pin在主机物理CPU上,以提高性能。可以增加CPU缓存命中率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
virsh vcpupin <vm-name>
假设物理和虚拟CPU都是两核
VCPU CPU Affinity
----------------------
0: 0-1
1: 0-1
表示可以在任何物理CPU上运行

# 将其固定到第一个CPU下
virsh vcpupin <vm-name> 0 0
virsh vcpupin <vm-name> 1 0

# 检查CPU亲和性
virsh vcpuinfo <vm-name>

# 给qemu分配专门CPU到CPU1上
virsh emulatorpin <vm-name> 1

虚拟机内存调优

限制host内存

  • 最大分配值:客户机运行时分配的最大内存
  • 当前分配值:小于或等于最大分配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
通过virsh dominfo查看

# 调整当前分配内存
virsh setmem
# 将正在运行的虚拟机内存调整为 4GB
virsh setmem my-vm 4096M --live

# 调整最大内存限制
virsh setmaxmem
# 永久设置最大内存为 8GB(需重启生效)
virsh setmaxmem my-vm 8192M --config
# 临时设置最大内存为 16GB(立即生效)
virsh setmaxmem my-vm 16384M --live

# 调整内存调优参数
virsh memtune
# 限制虚拟机最大内存使用为 4GB
virsh memtune my-vm --hard-limit 4194304 --live

hard_limit 绝对内存使用上限(物理内存+swap)
soft_limit 内存竞争时的优先保证量
swap_hard_limit 物理内存+swap 的总上限
min_guarantee 保证的最小内存(需特殊配置)

内核同页合并

当客户虚拟机运行相同的操作系统或工作负载时,很有可能许多内存页具有相同的内容。

内核共享内存,通过将相同的页面合并到一个内存页面来减少总内存使用量

当客户端必须通过写入来修改共享内存页面时,KSM克隆共享页面以给客户端一个新的非共享副本。这个过程称为写时复制(COW-copy on write)。

使用KSM需要两个服务,KSM是执行内存扫描和页面合并的服务,ksmtuned是控制KSM扫描内存的时间和力度的服务。

1
2
3
4
5
6
7
8
9
10
11
12
KSM可调项:
run:当设置为1时,ksm会主动扫描内存。当设置为0时,扫描被禁用。
pages_to_scan:下一个周期中要扫描的内存页数。
sleep_millisecs:周期之间休眠的毫秒数。
pages_shared:共享的页面总数。
pages_sharing:当前共享的页面数。
full_scans:整个内存被扫描的次数。
merge_across_nodes:来自不同NUMA节点的页面是否可以合并

# virsh node-memory-tune配置KSM可调项
指定在扫描进程休眠10毫秒之前要扫描的页面数量
virsh node-memory-tune --shm-pages-to-scan 100 --shm-sleep-millisecs 10

要调优KSM,使用ksmtuned服务通常比手工调优更有用。使用/etc/ksmtuning.conf文件配置ksmtuning服务。

磁盘I/O调优

客户虚拟磁盘可以是块设备,也可以是映像文件。块设备是虚拟磁盘的首选设备。与块设备相比,基于文件的映像文件增加了I/O操作的额外资源需求。与块设备相比,映像文件需要更多的资源进行I/O操作,因此需要进行磁盘调优。

qcow2镜像格式

qcow2格式的开销更大,因为它执行额外的任务。比如扩的时候会产生开销

特点

1.使用稀疏映像文件,这会导致过度分配主机存储。(精简置备)
qcow2 文件在创建时不会立即占用全部空间,而是按需增长。

2.将更改存储到另一个磁盘映像,而不实际影响原始映像的内容,该映像称为写时复制映像
修改操作不会直接写入基础镜像,而是记录到单独文件,

3.支持快照。快照是指使用Redirect-on-Write引用原始图像以避免更改原始图像的图像
快照是只读的
快照冻结原始状态,新数据写入独立空间

1
2
3
4
5
6
7
8
9
10
11
12
# 创建快照
virsh snapshot-create-as vm1 snap1

# 查看快照
virsh snapshot-list vm1

# 虚拟机执行操作:
rm -f /important-file

# 恢复到快照
virsh snapshot-revert vm1 snap1

4.支持压缩,并允许使用zlib压缩每个集群。使用集群存储设备的内容。
以 64KB 为单元压缩存储

5.支持集群加密

创建qcow2镜像

1
2
3
4
5
6
7
8
9
10
11
12
qemu-image create -f qcow2 -o preallocation-metadata disk.qcow2 1G

预分配模式:
preallocation=metadata:(精简置备)
此选项在创建映像时分配元数据所需的空间,而不是用于数据。这将
导致快速提供映像,但由于映像稀疏,所以来宾写入速度较慢。
preallocation=falloc:(元数据)
此选项在创建映像时分配元数据和数据所需的空间,但标记未分配的
块。这样可以快速提供映像,但比使用元数据选项要慢。磁盘写入速度更快。
preallocation=full:(完整制备)
该选项在映像创建过程中分配完整的文件大小,并且不使用任何稀疏技
术。这将导致映像的初始配置变慢。但是,在使用过程中,磁盘写性能与正常的falloc例程相同。

磁盘缓存模式

KVM允许在配置客户虚拟机时指定各种磁盘缓存

磁盘缓存模式影响如何读取和写入主机页缓存中的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cache=none(默认)
来自客户机的磁盘I/O不缓存在主机上,而是存储在物理磁盘缓存中。这个选项通常是最好的选择,并且支持迁移。

cache=writethrough(推荐)
来自客户机的磁盘I/O被缓存到主机上,并写入到物理磁盘。只有当数据被提交到物理磁盘时,才认为写操作完成。此选项可确保数据完整性,但写入速度较慢。

cache=writeback
来自客户机的磁盘I/O缓存在主机上。只有当数据提交到主机缓存时,才认为写操作完成。主机磁盘缓存管理提交到物理磁盘。

cache=directsync
来自客户机的磁盘I/O写入物理磁盘,并在需要时绕过主机缓存。只有当数据被提交到物理磁盘时,才认为写操作完成。此选项可确保数据完整性,但写入速度较慢。此选项对于不经常刷新磁盘I/O的客户机很有用。

cache=unsafe
这种模式类似于回写,但是来自客户端的所有磁盘I/O刷新命令都被忽略。该模式不能保证数据的完整性,但会提高磁盘的性能。例如,在来宾安装期间,缓存模式是最佳选择,但在生产工作负载上不是。
模式 数据安全 速度 类比 使用场景
none ★★★★☆ ★★★☆☆ 直发不存仓 日常生产环境 (推荐默认)
writethrough ★★★★★ ★★☆☆☆ 存仓+立即发货 金融/医疗等关键数据
writeback ★★☆☆☆ ★★★★★ 存仓=签收,延迟发货 非关键业务/高性能需求
directsync ★★★★★ ★☆☆☆☆ 亲自押运全程监控 极端安全需求
unsafe ☆☆☆☆☆ ★★★★★ 假签收永不发货 临时操作/绝对禁止生产环境

磁盘IO线程

I/O线程是受支持的磁盘设备的专用线程,用于执行块I/O请求,以提高可伸缩性。

一个主机CPU必须固定一个或两个I/O线程,每个虚拟块设备必须配置一个I/O线程以获得良好的性能

1
2
3
4
5
6
查看客户机每个IO线程数和CPU亲和性
virsh iothreadinfo <vm-name>

使用virsh iothreadadd命令为只读磁盘添加I/O线程。
virsh iothreadadd <vm-name> 2

虚拟磁盘调优

使用virsh blkdeviotune命令查看和设置连接到客户机的每个块设备上的吞吐量和I/O操作的限制。

1
2
virsh blkdeviotune <vm-name> vdb --total-iops-sec 1000 \
--total-bytes-sec 20MB

cgroup管理KVM虚拟机limit

默认情况下,libvirtd为主机上运行的虚拟机配置控制组。使用lscgroups命令查看cgroups定义。

但libvirtd守护进程提供了一个API,用于与分配给各个运行客户机的cgroup限制进行交互,所以可以直接使用virsh schedinfo命令查看和设置虚拟机的CPU相关限制。

1
2
3
4
5
6
7
8
9
10
11
12
设置CPU限制:
# 设置CPU权重为2048(双倍份额)
virsh schedinfo vm1 cpu_shares=2048

# 限制虚拟机最多使用50%的单核CPU
virsh schedinfo vm1 vcpu_period=100000 vcpu_quota=50000

# 限制整个虚拟机最多使用1.5个vCPU(150%)
virsh schedinfo vm1 global_quota=150000 global_period=100000

# 限制QEMU模拟器最多使用30%的CPU
virsh schedinfo vm1 emulator_quota=30000
可调项 默认值 含义说明 应用场景
cpu_shares 1024 CPU时间片相对权重,值越高获得的CPU时间越多。1024=标准权重,2048=2倍权重 CPU密集型负载
vcpu_period 100000 CPU配额周期长度(微秒),定义重新分配CPU时间的时间窗口 精确CPU控制
vcpu_quota -1(无限) 每个周期内允许的最大CPU时间(微秒)。-1=无限制,50000=单核50% CPU节流控制
emulator_period 100000 QEMU模拟器进程的CPU周期长度(微秒) 模拟器资源控制
emulator_quota -1(无限) QEMU模拟器在每个周期内允许的最大CPU时间(微秒) 模拟器节流
global_period 100000 整个虚拟机(vCPU+模拟器)的全局CPU周期长度(微秒) 整体资源控制
global_quota -1(无限) 整个虚拟机在每个全局周期内允许的最大CPU时间(微秒) 整体CPU限制
iothread_period 100000 虚拟机I/O线程的CPU周期长度(微秒) I/O性能优化
iothread_quota -1(无限) I/O线程在每个周期内允许的最大CPU时间(微秒) I/O节流控制
cap 0(禁用) 最大CPU使用率(百分比),200=2个vCPU满负载 绝对CPU限制
CATALOG
  1. 1. 虚拟机cpu调优
  2. 2. 虚拟机内存调优
    1. 2.1. 限制host内存
    2. 2.2. 内核同页合并
  3. 3. 磁盘I/O调优
    1. 3.1. qcow2镜像格式
    2. 3.2. 磁盘缓存模式
    3. 3.3. 磁盘IO线程
    4. 3.4. 虚拟磁盘调优
  4. 4. cgroup管理KVM虚拟机limit