当前位置: 欣欣网 > 码农

Linux 性能调优之虚拟化调优

2024-05-11码农

来源: 山河已无恙

写在前面

  • 考试整理相关笔记

  • 博文内容涉及Linux VM 常见管理操作以及部分调优配置

  • 理解不足小伙伴帮忙指正

  • 不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树

    使用工具进行调优

    可以直接使用 tuned 包里面的适用于虚拟化调优的参数,tuned 中对于虚拟化通过两个优化配置,一个适用虚拟机,一个适用虚拟机所在的宿主机。

    - virtual-guest - Optimize for running inside a virtual guest
    - virtual-host - Optimize for running KVM guests

  • virtual-guest:为运行在虚拟机客户机中进行优化,即虚拟机模式

  • virtual-host:为运行 KVM 客户机进行优化,运行了虚拟机的宿主机

  • 看一下这个两个策略配置做了什么操作

    虚拟机客户机策略,可以看到当前策略继承了下面的策略:

  • throughput-performance: 最大吞吐量 ,提供磁盘和网络 IO 的吞吐量

  • ┌──[[email protected]]-[~]
    └─$cat /usr/lib/tuned/virtual-guest/tuned.conf
    #
    # tuned configuration
    #
    [main]
    summary=Optimize for running inside a virtual guest
    include=throughput-performance
    [sysctl]
    # If a workload mostly uses anonymous memory and it hits this limit, the entire
    # working set is buffered for I/O, and any more write buffering would require
    # swapping, so it's time to throttle writes until I/O can catch up. Workloads
    # that mostly use file mappings may be able to use even higher values.
    #
    # The generator of dirty data starts writeback at this percentage (system default
    # is 20%)
    vm.dirty_ratio = 30
    # Filesystem I/O is usually much more efficient than swapping, so try to keep
    # swapping low. It's usually safe to go even lower than this on systems with
    # server-grade storage.
    vm.swappiness = 30

    修改了两个内核参数

    vm.dirty_ratio = 30
    vm.swappiness = 30

    vm.dirty_ratio :这个参数指定了当 匿名内存(anonymous memory)的脏页(dirty pages)达到一定比例时,开始进行写回(writeback) 。脏页是指已经被修改但尚未写入磁盘的页面。默认值是20%,而在这个配置中设置为30%。当脏页达到这个比例时,系统会开始将这些数据写回磁盘,以便为后续的写入操作腾出空间。 这个参数的增加可以延迟写回的触发,帮助提高I/O性能

    vm.swappiness :这个参数控制系统在内存紧张时进行页面置换(swapping)的倾向程度。页面置换指的是将内存中的页面数据移出到交换空间(swap space)中,以便为其他进程或文件提供更多的内存空间。默认值是60,而在这个配置中设置为30。 较低的值表示系统更倾向于使用文件系统的I/O操作来释放内存 ,而不是频繁进行页面置换。这对于使用高性能存储的服务器系统来说是安全的,可以降低页面置换的频率,提高整体性能。

    虚拟机的宿主机策略,通过继承了 throughput-performance 最大吞吐量策略

    ┌──[[email protected]]-[~]
    └─$cat /usr/lib/tuned/virtual-host/tuned.conf
    #
    # tuned configuration
    #
    [main]
    summary=Optimize for running KVM guests
    include=throughput-performance
    [sysctl]
    # Start background writeback (via writeback threads) at this percentage (system
    # default is 10%)
    vm.dirty_background_ratio = 5
    [cpu]
    # Setting C3 state sleep mode/power savings
    force_latency=cstate.id_no_zero:3|70
    ┌──[[email protected]]-[~]
    └─$

  • vm.dirty_background_ratio :这个参数指定了 当脏页的比例达到一定阈值时,系统开始后台写回(writeback) 。脏页是指已经被修改但尚未写入磁盘的页面。默认值是10%,而在这个配置中设置为5%。当脏页达到这个比例时,系统会启动后台的 写回线程 ,将部分数据写回磁盘,以减少内存中的脏页数量。通过降低这个阈值,可以在系统负载较轻时更早地开始后台写回,以提高整体的I/O性能。

  • [cpu] 部分中的 force_latency :这个配置参数用于设置CPU的C3状态(sleep mode)的睡眠模式或省电模式。 C3状态是一种较深的睡眠状态 ,可以在CPU空闲时进入以节省能源。这里的配置 cstate.id_no_zero:3|70 指示系统在空闲时将CPU进入C3状态,以实现一定程度的 省电 。具体的值和配置方式可能因硬件和内核版本而有所不同,这里的示例是针对特定的设置。

  • vm.dirty_background_ratio 参数和 vm.dirty_ratio 参数的区别:

  • vm.dirty_background_ratio 用通俗的话讲,可以驻留在内存中最大占比,即这些数据要写到磁盘,但是这个这个阈值之内不会发生回写。

  • vm.dirty_ratio 用通俗的话讲,当前系统能允许的最大脏页占比。当系统到达这一点时,所有新的 I/O 都会阻塞,直到脏页已写入磁盘

  • 资源占用信息查看

    ┌──[[email protected]]-[~]
    └─$yum -y install numactl

    numactl 是一个用于在 NUMA(非统一内存访问)系统上运行程序的实用工具。它可以帮助您管理和优化在 NUMA 架构下的内存访问和处理器分配。

    NUMA(Non-Uniform Memory Access) 是一种计算机系统架构,用于处理多处理器系统中的内存访问和内存管理。在NUMA架构中,系统中的内存被划分为多个节点(Node),每个节点与一个或多个处理器核心(CPU)相关联

    每个NUMA节点包含一部分物理内存和与之关联的处理器核心。节点之间通过高速互连(如快速路径互连或片上互连)连接起来,以实现节点之间的通信和数据传输

    使用numastat命令获取的关于qemu-kvm进程在不同NUMA节点上的内存使用情况的输出结果。

    ┌──[[email protected]]-[~]
    └─$numastat -c qemu-kvm
    Per-node process memory usage (in MBs)
    PID Node 0 Total
    --------------- ------ -----
    1755 (qemu-kvm) 855 855
    53693 (qemu-kvm) 759 759
    53790 (qemu-kvm) 1218 1218
    53890 (qemu-kvm) 875 875
    54009 (qemu-kvm) 751 751
    54128 (qemu-kvm) 811 811
    54246 (qemu-kvm) 778 778
    --------------- ------ -----
    Total 6048 6048

    设置虚拟机CPU绑定

    使用 virsh 工具对虚拟机的虚拟CPU(VCPU)进行查看绑定操作

    ┌──[[email protected]]-[~]
    └─$virsh vcpupin workstation
    VCPU: CPU Affinity
    ----------------------------------
    0: 0-7
    1: 0-7

    指定了名为"workstation"的虚拟机的VCPU绑定情况。根据输出,该虚拟机有两个VCPU(标识符为0和1),并且它们都与CPU编号0到7之间的CPU核心有绑定关系。

    ┌──[[email protected]]-[~]
    └─$virsh vcpupin servera
    VCPU: CPU Affinity
    ----------------------------------
    0: 0-7
    1: 0-7

    对名为"serverc"的虚拟机的第一个VCPU(标识符为0)进行了更具体的绑定设置。它将该VCPU绑定到了CPU编号为0的核心上。

    ┌──[[email protected]]-[~]
    └─$virsh vcpupin serverc 0 0
    ┌──[[email protected]]-[~]
    └─$virsh vcpupin serverc
    VCPU: CPU Affinity
    ----------------------------------
    0: 0
    1: 0-7

    0-5 表示将该 VCPU 绑定到 CPU 编号为 0到5的核心上。这意味着虚拟机的第一个VCPU只能在这些CPU核心上执行。

    ┌──[[email protected]]-[~]
    └─$virsh vcpupin serverc 0 0-5
    ┌──[[email protected]]-[~]
    └─$virsh vcpupin serverc
    VCPU: CPU Affinity
    ----------------------------------
    0: 0-5
    1: 0-7

    查看某个虚拟机的内存信息

    ┌──[[email protected]]-[~]
    └─$virsh dominfo workstation
    Id: 3
    Name: workstation
    UUID: 3f09a13c-94ad-4d97-8f76-17e9a81ae61f
    OS Type: hvm
    State: running
    CPU(s): 2
    CPU time: 771.0s
    Max memory: 2097152 KiB #虚拟机可用的最大内存容量,以KiB(Kibibyte)为单位。
    Used memory: 2097152 KiB #虚拟机当前使用的内存容量,以KiB为单位。
    Persistent: yes
    Autostart: disable
    Managed save: no
    Security model: selinux
    Security DOI: 0
    Security label: system_u:system_r:svirt_t:s0:c201,c330 (enforcing)

    限制虚拟机的 CPU 资源

    限制虚拟机的 CPU 资源, cpu shares=2048 的虚拟机会比 cpu shares=1024 的虚拟机获得更多的 CPU 资源

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh schedinfo workstation
    Scheduler : posix
    cpu_shares : 1024
    vcpu_period : 100000
    vcpu_quota : -1
    emulator_period: 100000
    emulator_quota : -1
    global_period : 100000
    global_quota : -1
    iothread_period: 100000
    iothread_quota : -1
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh schedinfo workstation cpu_shares=2048
    Scheduler : posix
    cpu_shares : 2048
    vcpu_period : 100000
    vcpu_quota : -1
    emulator_period: 100000
    emulator_quota : -1
    global_period : 100000
    global_quota : -1
    iothread_period: 100000
    iothread_quota : -1

    虚拟机 CPU份额(cpu shares) 参数的值为2048。CPU份额用于确定虚拟机在竞争CPU资源时的优先级。较高的份额值表示虚拟机将获得更多的CPU时间片。

    设置虚拟机内存限制

    设置 control 虚拟机的 最大内存容量 (确保虚拟机关机状态设置

    ┌──[[email protected]]-[~]
    └─$virsh setmaxmem workstation --size 2097152
    error: Unable to change MaxMemorySize
    error: Requested operation is not valid: cannot resize the maximum memory on an active domain

    设置 control 虚拟机的 运行内存容量 (确保虚拟机开机状态设置)

    ┌──[[email protected]]-[~]
    └─$virsh setmem workstation --size 2097152

    查看虚拟机内存限制

    ┌──[[email protected]]-[~]
    └─$virsh memtune workstation
    hard_limit : unlimited
    soft_limit : unlimited
    swap_hard_limit: unlimited

    设置虚拟机内存限制

    ┌──[[email protected]]-[~]
    └─$virsh memtune workstation --hard-limit 2G --soft-limit 1G
    ┌──[[email protected]]-[~]
    └─$virsh memtune workstation
    hard_limit : 2097152
    soft_limit : 1048576
    swap_hard_limit: unlimited
    ┌──[[email protected]]-[~]
    └─$

    KSM 参数配置

    多个虚拟机 运行相同的 操作系统 或者工作负载时,许多内存也很可能具有相同的内容,对这些 相同内存 内存页进行合并称为内核共享内存(KSM)

    当需要写入并修改共享内存时,KSM 会克隆共享页面,给虚拟机一个非共享的副本,这个过程称为 写时复制(COW,copy on write)

    ksm 进程 : 执行内存扫描和内存页合并

    ┌──[[email protected]]-[~]
    └─$systemctl status ksm
    ksm.service ksmtuned.service

    ┌──[[email protected]]-[~]
    └─$systemctl status ksm.service
    ● ksm.service - Kernel Samepage Merging
    Loaded: loaded (/usr/lib/systemd/system/ksm.service; enabled; vendor preset: enabled)
    Active: active (exited) since Mon 2023-10-02 19:31:31 CST; 2 days ago
     Main PID: 997 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 253184)
    Memory: 0B
    CGroup: /system.slice/ksm.service
    Oct 02 19:31:30 liruilongs.github.io systemd[1]: Starting Kernel Samepage Merging...
    Oct 02 19:31:31 liruilongs.github.io systemd[1]: Started Kernel Samepage Merging.

    ksmtuned 进程 :控制何时扫描以及扫描的积极性

    ┌──[[email protected]]-[~]
    └─$systemctl status ksmtuned.service
    ● ksmtuned.service - Kernel Samepage Merging (KSM) Tuning Daemon
    Loaded: loaded (/usr/lib/systemd/system/ksmtuned.service; enabled; vendor preset: enabled)
    Active: active (running) since Mon 2023-10-02 19:31:36 CST; 2 days ago
     Main PID: 1036 (ksmtuned)
    Tasks: 2 (limit: 253184)
    Memory: 12.9M
    CGroup: /system.slice/ksmtuned.service
    ├─ 1036 /bin/bash /usr/sbin/ksmtuned
    └─62516 sleep 60
    Oct 02 19:31:31 liruilongs.github.io systemd[1]: Starting Kernel Samepage Merging (KSM) Tuning Daemon...
    Oct 02 19:31:36 liruilongs.github.io systemd[1]: Started Kernel Samepage Merging (KSM) Tuning Daemon.
    ┌──[[email protected]]-[~]
    └─$

    可以通过 /sys/kerel/mm/ksm/ 目录下的参数,设置调优参数:

    ┌──[[email protected]]-[~]
    └─$cat /sys/kernel/mm/ksm/
    full_scans pages_to_scan stable_node_chains
    max_page_sharing pages_unshared stable_node_chains_prune_millisecs
    merge_across_nodes pages_volatile stable_node_dups
    pages_shared run use_zero_pages
    pages_sharing sleep_millisecs
    ┌──[[email protected]]-[~]
    └─$cat /sys/kernel/mm/ksm/run
    0
    ┌──[[email protected]]-[~]
    └─$

  • run :设置为 1 时,ksm 进程主动扫描内存,设置为 0 时,扫描被禁用。(默认为 0)

  • pages to scan :下一个周期要扫描的内存页数。(默认 100)sleep_millisecs:周期之间睡眠的时间,单位为毫秒。(默认 20)

  • pages shared :共享总页数。(默认 0)

  • pages_sharing :当前共享的页数。(默认 0)

  • fullscans :扫描整个内存空间的次数。(默认 0)

  • merge acrossnodes :是否合并不同 NUMA 节点的内存。(默认 1)

  • 可以通过 virsh node-memory-tune 命令查看这些参数的值,或者修改这些参数文件的值.

    nodecpustats nodedev-destroy nodedev-dumpxml nodedev-list nodedev-reset node-memory-tune nodesuspend
    ┌──[[email protected]]-[~]
    └─$virsh node-memory-tune
    Shared memory:
    shm_pages_to_scan 100
    shm_sleep_millisecs 20
    shm_pages_shared 2013
    shm_pages_sharing 5130
    shm_pages_unshared 10144
    shm_pages_volatile 91431
    shm_full_scans 28
    shm_merge_across_nodes 1
    ┌──[[email protected]]-[~]
    └─$virsh node-memory-tune --shm-sleep-millisecs 30
    ┌──[[email protected]]-[~]
    └─$virsh node-memory-tune
    Shared memory:
    shm_pages_to_scan 100
    shm_sleep_millisecs 30
    shm_pages_shared 2013
    shm_pages_sharing 5130
    shm_pages_unshared 10144
    shm_pages_volatile 91431
    shm_full_scans 28
    shm_merge_across_nodes 1
    ┌──[[email protected]]-[~]
    └─$cat /sys/kernel/mm/ksm/sleep_millisecs
    30
    ┌──[[email protected]]-[~]
    └─$

    虚拟磁盘配置调优

    虚拟机使用的磁盘可以是一个 块设备 ,也可以是一个 镜像文件

    直接使用 块设备 是一个不错的选择,而使用 镜像文件 则会带来额外的 I/O 资源 需求,镜像文件需要更多的 I/0 资源, KVM 支持 2 种镜像格式:

  • raw

  • qcow2

  • raw 格式性能比 qcow2 更好,但是 qcow2 可以获得更多功能。qcow2 可以提供如下功能:

  • sparse image file (稀疏镜像文件或精简像文件,真正使用时才分配存储空间)

  • Cow(写时复制)

  • ROW (写时重定向),应用于快照

  • compression(支持压缩)

  • encryption(支持加密)

  • 创建 qcow2 镜像

    使用 gemu-img create 命令可以创建 qcow2 镜像文件:

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/disk.qcow2 1G
    Formatting '/var/lib/libvirt/images/disk.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$ll /var/lib/libvirt/images/disk.qcow2
    -rw-r--r--. 1 root root 1074135040 Oct 5 14:17 /var/lib/libvirt/images/disk.qcow2
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$

    preallocation 支持的选择:

  • preallocation=off ,不分配任何空间,off 为默认属性

  • preallocation=metadata ,提前创建 metadata 空间,但不分配实际数据存储空间,快速创建镜像,但是写入速度会变慢。

  • preallocation=falloc ,创建 metadata 空间和数据空间,但是标记 block 为未分配,创建镜像比 metadata 慢,但是写入速度更快

  • preallocation=full ,创建镜像时分配所有资源,不使用 spare 技术。初始化镜像慢,性能类似 falloc。

  • 创建快照盘(ROW)

    基于 disk.qcow2 镜像文件,创建新的快照文件 disk-snap.qcow2 ,新像 30G

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$qemu-img create -f qcow2 -b /var/lib/libvirt/images/disk.qcow2 disk-snap.qcow2 30G
    Formatting 'disk-snap.qcow2', fmt=qcow2 size=32212254720 backing_file=/var/lib/libvirt/images/disk.qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$ll /var/lib/libvirt/images/disk-snap.qcow2
    -rw-r--r--. 1 root root 197088 Oct 5 14:25 /var/lib/libvirt/images/disk-snap.qcow2
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$

    虚拟机磁盘缓存模式

  • cache=none,不开启缓存,直接数据落盘,支持虚拟机迁移

  • cache=writethrough,数据同时写入缓存和物理硬盘,该选项确保数据完整性,但是写速度慢

  • cache=writeback,数据先写缓存,写入缓存及确认数据写入完成,然后缓存同步落盘

  • cache=directsync,类似 writethrouth,数据写入物理硬盘,需要的时候绕过缓存

  • cache=unsafe,类似于 writeback,但是所有 /O flush 都会被忽略,不确保数据安全,但是可以提升性能,比如在安装系统时使用该模式,但是不能应用在生产工作负载

  • ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$cat *.xml | grep driver
    <driver name="qemu"type="qcow2" cache='none'/>

    虚拟机磁盘 IO 调优

    使用virsh blkdeviotune命令来为名为"workstation"的虚拟机的磁盘设备(vda)设置了 I/O限制 。具体来说,设置了每秒最大 IOPS(IO操作每秒)为1000 ,并设置了每秒最大字节传输速率为10MB。

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh blkdeviotune workstation vda --total-iops-sec 1000 --total-bytes-sec 10MB
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh dumpxml workstation | grep -A2 iotune
    <iotune>
    <total_bytes_sec>10000000</total_bytes_sec>
    <total_iops_sec>1000</total_iops_sec>
    </iotune>
    <alias name='virtio-disk0'/>
    <address type='pci' domain='0x0000' bus='0x04' slot='0x00'function='0x0'/>
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$

    虚拟化性能监控

    查看设备 IO 信息

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh domblkstat workstation vda --human
    Device: vda
     number of read operations: 15012
     number of bytes read: 437122048
     number of write operations: 3193
     number of bytes written: 71808512
     number of flush operations: 903
     total duration of reads (ns): 854291749703
     total duration of writes (ns): 93692774619
     total duration of flushes (ns): 7848596731

    查看网络设备信息

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh domiflist workstation
    Interface Type Source Model MAC
    -------------------------------------------------------
    vnet4 bridge privbr0 virtio 52:54:00:00:fa:09

    查看网络状态

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh domifstat workstation vnet4
    vnet4 rx_bytes 600038
    vnet4 rx_packets 10176
    vnet4 rx_errs 0
    vnet4 rx_drop 0
    vnet4 tx_bytes 72045
    vnet4 tx_packets 610
    vnet4 tx_errs 0
    vnet4 tx_drop 0

    查看内存信息,单位为 KB

    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$virsh dommemstat workstation
    actual 2097152
    swap_in 0
    swap_out 0
    major_fault 304
    minor_fault 147927
    unused 1669348
    available 1873292
    usable 1631560
    last_update 1696474286
    rss 1246776
    ┌──[[email protected]]-[/var/lib/libvirt/images]
    └─$

    博文部分内容参考

    © 文中涉及参考链接内容版权归原作者所有,如有侵权请告知,这是一个开源项目,如果你认可它,不要吝啬星星哦 :)

    https://lonesysadmin.net/tag/linux-vm-performance-tuning/

    【 Red Hat Performance Tuning 442 】

    © 2018-2024 [email protected], All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)