當前位置: 妍妍網 > 碼農

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)