Оптимизация производительности виртуальных машин#

Производительность ВМ по сравнению с хостом в процессе эксплуатации часто снижается. Причины этого снижения приведены в разделе «Причины снижения производительности виртуальных машин».

Влияние виртуализации на производительность в SberLinux OS Server можно свести к минимуму в целях максимально эффективного использования выбранной аппаратной инфраструктуры.

Причины снижения производительности виртуальных машин#

ВМ запускаются как процессы пользовательского пространства на хосте. Гипервизор должен преобразовать системные ресурсы хоста, чтобы ВМ могли их использовать. Часть ресурсов в этом случае расходуется на преобразование, поэтому ВМ не достигает той же эффективности производительности, что и хост.

Влияние виртуализации на производительность системы#

Частые причины потери производительности ВМ:

  • Реализация виртуальных процессоров (vCPU) на хосте в виде потоков, обрабатываемых планировщиком Linux.

  • Отсутствие автоматического наследования ВМ функций оптимизации, таких как NUMA или hugepages, от ядра хоста.

  • Влияние дисковых и сетевых настроек ввода-вывода хоста.

  • Поступление сетевого трафика на ВМ через программный мост.

  • Расходы из-за эмуляции определенного оборудования, зависящие от хост-устройств и их моделей.

Уровень влияния виртуализации на производительность ВМ влияют различные факторы, которые включают в себя:

  • Количество одновременно работающих ВМ.

  • Количество виртуальных устройств, используемых каждой ВМ.

  • Типы устройств, используемые ВМ.

Снижение потери производительности виртуальных машин#

В SberLinux OS пользователю предоставляется ряд функций, которые можно использовать для снижения негативных эффектов виртуализации:

  • Служба TuneD. Может автоматически оптимизировать распределение ресурсов и производительность ВМ.

  • Настройка блочного ввода-вывода. Улучшает производительность блочных устройств ВМ, таких, как диски.

  • Настройка NUMA. Повышает производительность vCPU.

  • Оптимизация виртуальных сетей.

Важно

Настройка производительности ВМ может негативно сказаться на других функциях виртуализации. Например, это может затруднить миграцию модифицированной ВМ.

Оптимизация производительности виртуальной машины с помощью TuneD#

Утилита TuneD - это механизм доставки профиля настройки, который адаптирует ОС для определенных характеристик рабочей нагрузки, таких как требования к задачам с высокой загрузкой ЦП или пропускной способности сети хранения данных. TuneD предоставляет ряд профилей настройки, которые предварительно настроены для повышения производительности и снижения энергопотребления в ряде конкретных случаев использования. Профили можно редактировать или создавать новые для создания решений повышения производительности, адаптированных к среде, включая виртуализированные среды.

Чтобы оптимизировать ОС для виртуализации, используйте следующие профили:

  • Для ВМ SberLinux OS используйте профиль virtual-guest. Он основан на общепринятом профиле throughput-performance, однако снижает дисковую буферизацию (swappiness) виртуальной памяти.

  • Для хостов виртуализации SberLinux OS используйте профиль virtual-host. Данный профиль позволяет более интенсивно производить запись страниц «грязной памяти», что способствует росту производительности хоста.

Примечание

«Грязной памятью» или «грязными страницами памяти» в контексте виртуализации обычно называют страницы памяти, которые уже были перенесены на целевой хост или на диск, но после этого на исходном хосте они были изменены и теперь требуют повторного перемещения.

Предварительные условия#

TuneD установлена и включена.

Сценарий#

Чтобы включить определенный профиль TuneD:

  1. Получите список доступных профилей TuneD с помощью команды:

    tuned-adm list
    

    Пример вывода команды:

    Available profiles:
    - balanced             - General non-specialized TuneD profile
    - desktop              - Optimize for the desktop use-case
    [...]
    - virtual-guest        - Optimize for running inside a virtual guest
    - virtual-host         - Optimize for running KVM guests
    Current active profile: balanced
    
  2. Необязательно: создайте новый профиль TuneD или отредактируйте существующий профиль TuneD.

  3. Активируйте профиль TuneD командой:

    tuned-adm profile selected-profile
    
    • Чтобы оптимизировать хост виртуализации, используйте профиль virtual-host:

      tuned-adm profile virtual-host
      
    • В гостевой ОС SberLinux OS используйте профиль virtual-guest:

      tuned-adm profile virtual-guest
      

Настройка памяти виртуальной машины#

Для повышения производительности ВМ, можно назначить ей дополнительную оперативную память хоста. Аналогичным образом, можно уменьшить объем памяти, выделенный конкретной ВМ, чтобы память хоста могла быть предоставлена другим ВМ или задачам.

Добавление и удаление памяти виртуальной машины с помощью интерфейса командной строки#

Чтобы повысить производительность ВМ или освободить ресурсы хоста, которые она использует, можно использовать CLI для настройки объема памяти, выделяемой для данной ВМ.

Предварительные условия#

Перед настройкой рекомендуется убедиться, что в гостевой ОС работают драйверы memory ballon.

Для проверки выполните следующие действия:

  1. Убедитесь, что конфигурация ВМ включает в себя устройство memballoon:

    virsh dumpxml <example-vm> | grep memballoon
    

    Пример вывода команды:

    <memballoon model='virtio'>
        </memballoon>
    

    Если в результате работы команды отображается какой-либо вывод, а значение поля model не установлена на none, то устройство memballoon в конфигурации присутствует.

  2. Убедитесь, что драйверы balloon работают в гостевой ОС:

    • для гостевых ОС Windows драйверы устанавливаются как часть пакета драйверов virtio-win;

    • для гостевых ОС Linux драйверы, как правило, включены по умолчанию и активируются при наличии устройства memballoon.

Сценарий#

  1. Необязательно: выведите информацию о максимальной памяти и используемой в настоящее время памяти для ВМ с помощью команды:

    virsh dominfo <example-vm>
    

    Пример вывода команды:

    Max memory:     2097152 KiB
    Used memory:    2097152 KiB
    

    Информация выше требуется для изменений и проверки.

  2. Настройте максимальный объем памяти, выделенный ВМ, с помощью команды:

    virt-xml <example-vm> --edit --memory memory=4096,currentMemory=4096
    

    Команда изменит максимальную память, которую может использовать ВМ <example-vm>, на 4096 Мбайт.

    Пример вывода команды:

    Domain '<example-vm>' defined successfully.
    Changes will take effect after the domain is fully powered off.
    

    Увеличение максимального значения памяти повышает потенциал производительности ВМ, а уменьшение снижает производительность ВМ на хосте.

    Внимание

    Данное изменение может быть выполнено только на выключенной ВМ. Для настройки работающей ВМ требуется перезагрузка.

    Чтобы увеличить максимальное значение памяти запущенной ВМ, можно подключить к ней устройство памяти. Это также называется «горячим» подключением памяти.

    Внимание

    Удаление устройств памяти из запущенной ВМ или «горячее» отключение памяти не поддерживается и настоятельно не рекомендуется.

  3. Необязательно: настройте текущий объем памяти, используемой ВМ на хосте, без изменения максимального значения памяти, выделенного ВМ, с помощью команды:

    virsh setmem <example-vm> --current 2048
    

    Команда установит объем памяти, который есть у ВМ на хосте до следующей перезагрузки.

Проверка#

  1. Убедитесь, что значение памяти, используемой ВМ, было обновлено:

    virsh dominfo <example-vm>
    

    Пример вывода команды:

    Max memory:     4194304 KiB
    Used memory:    2097152 KiB
    
  2. Необязательно: если была произведена настройка текущей памяти ВМ, просмотрите статистику по выделению памяти ВМ, чтобы оценить, насколько эффективно она ее использует:

    virsh domstats --balloon <example-vm>
    

    Пример вывода команды:

    Domain: '<example-vm>'
      balloon.current=365624
      balloon.maximum=4194304
      balloon.swap_in=0
      balloon.swap_out=0
      balloon.major_fault=306
      balloon.minor_fault=156117
      balloon.unused=3834448
      balloon.available=4035008
      balloon.usable=3746340
      balloon.last-update=1587971682
      balloon.disk_caches=75444
      balloon.hugetlb_pgalloc=0
      balloon.hugetlb_pgfail=0
      balloon.rss=1005456
    

Дополнительная информация#

Дополнительную информацию можно получить в разделе «Оптимизация производительности ЦП виртуальной машины».

Оптимизация производительности ввода-вывода виртуальной машины#

Возможности ввода и вывода (I/O) ВМ могут значительно ограничить общую эффективность ВМ. Существует возможность оптимизировать ввод-вывод ВМ, настроив параметры блочного ввода-вывода.

Настройка блочного ввода-вывода в виртуальных машинах#

Когда несколько блочных устройств используются одной или несколькими ВМ, важно настроить приоритет ввода-вывода определенных виртуальных устройств путем изменения весовых коэффициентов для операций их ввода-вывода.

Увеличение веса ввода-вывода устройства увеличивает его приоритет для пропускной способности ввода-вывода и, следовательно, предоставляет ему больше ресурсов хоста. Аналогичным образом, снижение веса устройства заставляет его потреблять меньше ресурсов хоста.

Примечание

Вес каждого устройства должен находиться в диапазоне от 100 до 1000. Значение 0 означает, что данное устройство будет удалено из списков устройств.

Сценарий#

Для отображения и установки параметров блочного ввода-вывода ВМ выполните следующие шаги:

  1. Выведите информацию о текущих параметрах <blkio> для ВМ:

    virsh dumpxml <example-vm>
    

    Пример вывода команды:

    <domain>
      [...]
      <blkiotune>
        <weight>800</weight>
        <device>
          <path>/dev/sda</path>
          <weight>1000</weight>
        </device>
        <device>
          <path>/dev/sdb</path>
          <weight>500</weight>
        </device>
      </blkiotune>
      [...]
    </domain>
    
  2. Отредактируйте вес ввода-вывода указанного устройства:

    virsh blkiotune <example-vm> --device-weights <device>, <I/O-weight>
    

    Где:

    • <device> – устройство, вес которого требуется изменить, например, /dev/sda в примере конфигурации выше;

    • <I/O-weight> – значение веса устройства, которое требуется установить, например, 500.

Регулирование операций ввода-вывода дисковых устройств в виртуальных машинах#

Одновременная работа нескольких ВМ может влиять на общую производительность системы из-за использования большого количества операций ввод-вывода дисковых устройств. Механизм регулирования в KVM позволяет устанавливать ограничение на запросы данного ввода-вывода, отправляемые с ВМ на хост. Процесс регулирования может предотвратить чрезмерное использование ВМ общих ресурсов и их влияние на производительность.

Чтобы включить механизм регулирования ввода-вывода дисковых устройств, необходимо установить ограничение на запросы, отправляемые с каждого блочного устройства, подключенного к виртуальным машинам, на хост.

Сценарий#

  1. Выведите список имен всех дисковых устройств на выбранной ВМ с помощью команды:

    virsh domblklist <example-vm>
    

    Пример вывода команды:

    Target     Source
    ------------------------------------------------
    vda        /var/lib/libvirt/images/<example-vm>.qcow2
    sda        -
    sdb        /home/horridly-demanding-processes.iso
    
  2. Определите блочное устройство со смонтированным виртуальным диском на хосте, для которого нужно включить механизм регулирования:

    lsblk
    

    Пример вывода команды:

    NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
    zram0                                         252:0    0     4G  0 disk  [SWAP]
    nvme0n1                                       259:0    0 238.5G  0 disk
    ├─nvme0n1p1                                   259:1    0   600M  0 part  /boot/efi
    ├─nvme0n1p2                                   259:2    0     1G  0 part  /boot
    └─nvme0n1p3                                   259:3    0 236.9G  0 part
        └─luks-a1123911-6f37-463c-b4eb-fxzy1ac12fea  253:0    0 236.9G  0 crypt /home
    

    Например, если требуется включить регулирование на виртуальном диске sdb из предыдущего шага, вывод команды показывает, что диск смонтирован на разделе /dev/nvme0n1p3.

  3. Установите ограничения ввода-вывода для блочного устройства с помощью команды:

    virsh blkiotune <example-vm> --parameter <device>,<limit>
    

    Где:

    • <device> - устройство;

    • <limit> – значение требуемого ограничения.

    Например, если требуется установить ограничение для диска sdb на ВМ <example-vm> до 1000 операций ввода-вывода для чтения и записи в секунду и до 50 МБ в секунду пропускной способности чтения и записи, то команда выше будет выглядеть следующим образом:

    virsh blkiotune <example-vm> --device-read-iops-sec /dev/nvme0n1p3,1000 --device-write-iops-sec /dev/nvme0n1p3,1000 --device-write-bytes-sec /dev/nvme0n1p3,52428800 --device-read-bytes-sec /dev/nvme0n1p3,52428800
    

Дополнительная информация#

Регулирование ввода-вывода дисковых устройств может быть полезно в ситуациях, например, когда ВМ, принадлежащие разным клиентам, работают на одном хосте или когда для разных ВМ даются гарантии качества обслуживания. Также механизм регулирования может использоваться для моделирования ситуации работы с медленными дисками.

Регулирование ввода-вывода может применяться независимо к каждому блочному устройству, подключенному к ВМ, и поддерживает ограничения пропускной способности и операций ввода-вывода.

Внимание

SberLinux OS не поддерживает использование команды virsh blkdeviotune для настройки регулирования ввода-вывода в виртуальных машинах.

Включение нескольких очередей для virtio-scsi#

При использовании устройств хранения virtio-scsi в ВМ функция multi-queue virtio-scsi обеспечивает улучшенную производительность и масштабируемость хранилища. Это позволяет каждому виртуальному ЦП (vCPU) использовать отдельную очередь и прерывание без оказания влияния на другие vCPU.

Сценарий#

Чтобы включить поддержку функции multi-queue virtio-scsiдля конкретной ВМ, добавьте следующую информацию в XML-конфигурацию ВМ:

<controller type='scsi' index='0' model='virtio-scsi'>
   <driver queues='N' />
</controller>

Где N - общее количество очередей vCPU.

Оптимизация производительности ЦП виртуальной машины#

Как и физические процессоры на хостах, vCPU оказывают значительное влияние на производительность ВМ и эффективность их использования.

Чтобы оптимизировать vCPU:

  1. Назначьте ВМ требуемое количество физических ЦП на хосте с помощью CLI.

  2. Убедитесь, что модель vCPU соответствует модели физического процессора хоста, и настройте ВМ на нужную модель процессора с помощью команды:

    virt-xml <example-vm> --edit --cpu host-model
    

    Команда настроит ВМ <example-vm> на использование модели процессора хоста.

    Примечание

    В системе ARM 64 используйте --cpu host-passthrough.

  3. Используйте функцию Kernel Same-Page Merging (KSM) для улучшения плотности памяти с помощью разделения идентичных страницы памяти между ВМ.

    Примечание

    Включение KSM увеличивает загрузку ЦП и может отрицательно повлиять на общую производительность в зависимости от рабочей нагрузки. В SberLinux OS версии KSM по умолчанию отключен.

  4. Настройте Non-Uniform Memory Access (NUMA) для ВМ, если хост использует неравномерный доступ к NUMA. Данная настройка обеспечивает максимально точное сопоставление процессов ЦП и памяти хоста с процессами ЦП и памяти ВМ, а также оптимизированный доступ vCPU к системной памяти, выделенной для ВМ, для более эффективной обработки vCPU.

Добавление и удаление виртуальных процессоров с помощью интерфейса командной строки#

Чтобы увеличить или оптимизировать производительность vCPU, можно добавить или удалить vCPU, назначенные ВМ.

Примечание

Добавление и удаление vCPU на включенной ВМ называется «горячим подключением» и «горячим отключением» vCPU. «Горячее отключение» vCPU не поддерживается в SberLinux OS и его не следует использовать.

Предварительные условия#

Опционально: перед добавлением или удалением vCPU просмотрите текущее состояние vCPU на целевой ВМ с помощью команды:

virsh vcpucount <example-vm>

Команда выведет информацию о количестве vCPU на ВМ <example-vm>.

Пример вывода команды:

maximum      config         4
maximum      live           2
current      config         2
current      live           1

Вывод команды указывает на то, что <example-vm> в настоящее время использует 1 vCPU, и еще 1 vCPu может быть подключен «горячим подключением» для повышения производительности ВМ.

Внимание

После перезагрузки количество vCPU <example-vm> изменится на 2. С помощью «горячего подключения» можно будет подключить еще 2 vCPU.

Сценарий#

  1. Отрегулируйте максимальное количество vCPU, которые могут быть подключены к ВМ:

    virsh setvcpus <example-vm> 8 --maximum --config
    

    Команда увеличит максимальное количество vCPU для ВМ <example-vm> до 8. Изменения вступят в силу при следующей загрузке ВМ.

    Внимание

    Максимальное количество vCPU может быть ограничено топологией процессора, аппаратным обеспечением хоста, гипервизором и другими факторами.

  2. Отрегулируйте текущее количество vCPU, подключенных к ВМ, до максимального количества, настроенного на предыдущем шаге:

    • Чтобы увеличить количество vCPU, подключенных к запущенной ВМ <example-vm>, до 4, используйте команду:

      virsh setvcpus <example-vm> 4 --live
      

      Данная команда повышает производительность ВМ <example-vm> и нагрузку на хост до следующей загрузки ВМ.

    • Чтобы уменьшить количество виртуальных процессоров, подключенных к ВМ <example-vm>, до 1 при последующих запусках, используйте команду:

      virsh setvcpus <example-vm> 1 --config
      

      Данная команда снижает производительность ВМ <example-vm> и нагрузку хоста после следующей загрузки ВМ. При необходимости можно подключить к ВМ дополнительные vCPU, чтобы временно повысить ее производительность.

Проверка#

Убедитесь, что текущее состояние vCPU для ВМ отражает внесенные изменения:

virsh vcpucount <example-vm>

Пример вывода команды:

maximum      config         8
maximum      live           4
current      config         1
current      live           4

Настройка NUMA в виртуальной машине#

Для настройки NUMA ВМ на хосте SberLinux OS используйте сценарий, приведенный ниже.

Предварительные условия#

Перед настройкой определите совместим ли хост с NUMA с помощью команды:

virsh nodeinfo

Пример вывода команды:

CPU model:           x86_64
CPU(s):              48
CPU frequency:       1200 MHz
CPU socket(s):       1
Core(s) per socket:  12
Thread(s) per core:  2
NUMA cell(s):        2
Memory size:         67012964 KiB

В выводе команды проанализируйте строку NUMA cell(s). Если значение строки 2 или больше, хост совместим с NUMA.

Сценарий#

Конфигурацию NUMA ВС можно настроить с помощью автоматизированных утилит и служб, а также вручную. Ручная настройка NUMA с большей вероятностью приведет к значительному улучшению производительности.

Автоматические методы настройки NUMA#
  • Установите политику NUMA ВМ в Preferred с помощью команды:

    virt-xml <example-vm> --edit --vcpus placement=auto
    

    И команды:

    virt-xml <example-vm> --edit --numatune mode=preferred
    

    Команды настроят политику Preferred для ВМ <example-vm>.

  • Включите автоматическую балансировку NUMA на хосте:

    echo 1 > /proc/sys/kernel/numa_balancing
    
  • Для автоматического выравнивания процессора ВМ с ресурсами памяти используйте следующую команду:

    numad
    
Ручные методы#
  1. Закрепите определенные потоки vCPU за определенным ЦП хоста или диапазоном процессоров с помощью команд:

    virsh vcpupin <example-vm> 0 1
    
    virsh vcpupin <example-vm> 1 3
    
    virsh vcpupin <example-vm> 2 5
    
    virsh vcpupin <example-vm> 3 7
    
    virsh vcpupin <example-vm> 4 9
    
    virsh vcpupin <example-vm> 5 11
    

    Команды выше прикрепляют потоки vCPU 0 - 5 ВМ <example-vm> к ЦП хоста 1, 3, 5, 7, 9 и 11.

    Проверить, вступили ли в силу изменения, можно с помощью команды:

    virsh vcpupin <example-vm>
    

    Пример вывода команды:

    vCPU   CPU Affinity
    ----------------------
    0      1
    1      3
    2      5
    3      7
    4      9
    5      11
    

    Примечание

    Закрепление потоков также возможно на хостах и ВМ, не поддерживающих NUMA, и рекомендуется в качестве безопасного метода повышения производительности vCPU.

  2. Прикрепите потоки процесса QEMU, связанные с соответствующей ВМ, к определенному ЦП хоста или диапазону процессоров с помощью команд:

    virsh emulatorpin <example-vm> 13,15
    

    И:

    virsh emulatorpin <example-vm>
    

    Первая команды закрепляет поток процесса QEMU ВМ <example-vm> к процессорам 13 и 15. Вторая команда проверяет успешность данного закрепления.

    Пример вывода команды проверки:

    emulator: CPU Affinity
    ----------------------------------
           *: 13,15
    
  3. Укажите, какие узлы NUMA на хосте будут назначены конкретной ВМ, с помощью команд:

    virsh numatune <example-vm> --nodeset 3-5
    

    И:

    virsh numatune <example-vm>
    

    Первая команды устанавливает для использования <example-vm> узлы NUMA хоста с 3 по 5. Вторая команда проверяет, что первая команда выполнена успешно. Данный процесс улучшает использование памяти хоста vCPU ВМ.

Примечание

Для достижения наилучших результатов рекомендуется использовать все перечисленные выше методы ручной настройки.

Дополнительная информация#

Дополнительную информацию можно получить в разделах «Пример сценария настройки производительности vCPU» и «Инструменты мониторинга производительности виртуальной машины».

Пример сценария настройки производительности vCPU#

Чтобы получить наилучшую производительность vCPU, следует совместно использовать ручные настройки vcpupin, emulatorpin и numatune.

Стартовые условия#

  • Начальные характеристики хоста:

    • 2 узла NUMA;

    • 3 процессорных ядра на каждом узле:

    • 2 потока у каждого ядра.

    Вывод команды virsh nodeinfo для условий выше будет выглядеть так:

    CPU model:           x86_64
    CPU(s):              12
    CPU frequency:       3661 MHz
    CPU socket(s):       2
    Core(s) per socket:  3
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         31248692 KiB
    
  • Необходимые изменения: существующая ВМ должна иметь 8 виртуальных процессоров и размещена на нескольких узлах NUMA. Для реализации изменений необходимо распределить 4 vCPU на каждом узле NUMA и сделать так, чтобы топология vCPU была как можно ближе к топологии хоста. Виртуальные процессоры, которые работают как потоки-близнецы на каждом физическом процессоре, должны быть закреплены на потоках хоста на том же ядре.

Сценарий#

  1. Получите информацию о топологии хоста с помощью команды:

    virsh capabilities
    

    Вывод должен включать раздел <topology>:

    <topology>
      <cells num="2">
        <cell id="0">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="10" />
            <sibling id="1" value="21" />
          </distances>
          <cpus num="6">
            <cpu id="0" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="1" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="2" socket_id="0" core_id="2" siblings="2,5" />
            <cpu id="3" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="4" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="5" socket_id="0" core_id="2" siblings="2,5" />
          </cpus>
        </cell>
        <cell id="1">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="21" />
            <sibling id="1" value="10" />
          </distances>
          <cpus num="6">
            <cpu id="6" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="7" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="8" socket_id="1" core_id="5" siblings="8,11" />
            <cpu id="9" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="10" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="11" socket_id="1" core_id="5" siblings="8,11" />
          </cpus>
        </cell>
      </cells>
    </topology>
    
  2. Опционально: проверьте производительность ВМ с помощью соответствующих инструментов и утилит, приведенных в разделе «Инструменты мониторинга производительности виртуальной машины».

  3. Настройте и установите 1 ГиБ «больших страниц» памяти на хосте:

    Примечание

    «Большие страницы» памяти размером 1 ГиБ могут быть недоступны в некоторых архитектурах и конфигурациях, например, на хостах ARM 64.

    1. Добавьте следующую информацию в командную строку ядра хоста:

      default_hugepagesz=1G hugepagesz=1G
      
    2. Создайте файл /etc/systemd/system/hugetlb-gigantic-pages.service со следующим содержимым:

      [Unit]
      Description=HugeTLB Gigantic Pages Reservation
      DefaultDependencies=no
      Before=dev-hugepages.mount
      ConditionPathExists=/sys/devices/system/node
      ConditionKernelCommandLine=hugepagesz=1G
      
      [Service]
      Type=oneshot
      RemainAfterExit=yes
      ExecStart=/etc/systemd/hugetlb-reserve-pages.sh
      
      [Install]
      WantedBy=sysinit.target
      
    3. Создайте файл /etc/systemd/hugetlb-reserve-pages.sh со следующим содержимым:

      #!/bin/sh
      
      nodes_path=/sys/devices/system/node/
      if [ ! -d $nodes_path ]; then
         echo "ERROR: $nodes_path does not exist"
         exit 1
      fi
      
      reserve_pages()
      {
         echo $1 > $nodes_path/$2/hugepages/hugepages-1048576kB/nr_hugepages
      }
      
      reserve_pages 4 node1
      reserve_pages 4 node2
      

      Скрипт выше резервирует 4 hugepages 1GiB от node1 и 4 hugepages 1GiB от node2.

    4. Сделайте скрипт, созданный на предыдущем шаге, исполняемым:

      chmod +x /etc/systemd/hugetlb-reserve-pages.sh
      
    5. Включите резервирование hugepages при загрузке:

      systemctl enable hugetlb-gigantic-pages
      
  4. Отредактируйте XML-конфигурацию ВМ <example-vm>, которую нужно оптимизировать, с помощью команды:

    virsh edit <example-vm>
    
  5. Настройте XML-конфигурацию ВМ:

    1. Настройте ВМ на использование 8 статических виртуальных процессоров с помощью элемента <vcpu/>.

    2. Закрепите каждый из потоков vCPU за соответствующими потоками процессора хоста, которые отражаются в топологии, с помощью элементов <vcpupin/> в разделе <cputune>:

      Внимание

      Потоки ЦП хоста не упорядочены последовательно в соответствующих ядрах, что иллюстрирует вывод команды virsh capabilities в шаге 1. Потоки vCPU должны быть закреплены за самым высокодоступным набором ядер хоста на том же узле NUMA.

      XML-конфигурация после шагов 1 и 2 может выглядеть так:

      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
      
    3. Настройте ВМ на использование 1 ГиБ hugepages:

      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
      
    4. Настройте узлы NUMA ВМ на использование памяти из соответствующих узлов NUMA на хосте с помощью элементов <memnode/> в разделе <numatune/>:

      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
      
    5. Убедитесь, что режим процессора установлен на host-passthrough и что процессор использует кеш в режиме passthrough:

      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
      

Проверка#

  1. Убедитесь, что результирующая XML-конфигурация ВМ включает в себя подобный раздел:

    [...]
      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
      <vcpu placement='static'>8</vcpu>
      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
        <numa>
          <cell id="0" cpus="0-3" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="10"/>
              <sibling id="1" value="21"/>
            </distances>
          </cell>
          <cell id="1" cpus="4-7" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="21"/>
              <sibling id="1" value="10"/>
            </distances>
          </cell>
        </numa>
      </cpu>
    </domain>
    
  2. Опционально: проверьте производительность ВМ с помощью инструментов и утилит для оценки влияния оптимизации ВМ. Информация об инструментах и утилитах приведена в разделе «Инструменты мониторинга производительности виртуальной машины».

Управление слиянием одинаковых страниц ядра#

Слияние одинаковых страниц ядра Kernel Same-Page Merging (KSM) улучшает плотность памяти, за счет совместного использования идентичных страниц памяти между ВМ. Однако KSM может увеличить использование ЦП и негативно повлиять на общую производительность в зависимости от рабочей нагрузки.

KSM можно включить или отключить для одного сеанса или на постоянной основе.

Примечание

В SberLinux OS Server KSM отключен по умолчанию.

Предварительные условия#

У пользователя должны быть административные полномочия для доступа к хосту.

Сценарий#

  • Отключение KSM:

    • Для отключения KSM для одного сеанса, остановите службы ksm и ksmtuned с помощью команд:

      systemctl stop ksm
      

      И:

      systemctl stop ksmtuned
      
    • Для отключения KSM на постоянной основе используйте команды:

      systemctl disable ksm
      

      Пример вывода команды:

      Removed /etc/systemd/system/multi-user.target.wants/ksm.service.
      

      И:

      systemctl disable ksmtuned
      

      Пример вывода команды:

      Removed /etc/systemd/system/multi-user.target.wants/ksmtuned.service.
      

    Примечание

    Совместно используемые ВМ страницы памяти до отключения KSM останутся общими. Чтобы прекратить совместное использование, удалите все PageKSM в системе, используя следующую команду:

    echo 2 > /sys/kernel/mm/ksm/run
    

    После того как анонимные страницы заменят страницы KSM, служба ядра khugepaged восстановит transparent hugepages в физической памяти ВМ.

    Примечание

    Transparent HugePage (THP) - это альтернативный способ использования hugepages для резервного копирования виртуальной памяти, который поддерживает автоматическое увеличение и понижение размеров страниц.

  • Включение KSM:

    Важно

    Включение KSM увеличивает загрузку процессора и влияет на его общую производительность.

    1. Установите сервис ksmtuned:

      dnf install ksmtuned
      
    2. Запустите сервис:

      • Чтобы включить KSM для одного сеанса, запустите службы ksm и ksmtuned с помощью команд:

        systemctl start ksm
        

        И:

        systemctl start ksmtuned
        
      • Чтобы включить KSM на постоянной основе, используйте команды:

        systemctl enable ksm
        

        Пример вывода команды:

        Created symlink /etc/systemd/system/multi-user.target.wants/ksm.service  /usr/lib/systemd/system/ksm.service
        

        И:

        systemctl enable ksmtuned
        

        Пример вывода команды:

        Created symlink /etc/systemd/system/multi-user.target.wants/ksmtuned.service  /usr/lib/systemd/system/ksmtuned.service
        

Оптимизация производительности сети виртуальных машин#

Сетевой интерфейс ВМ virtual network interface card (vNIC) теряет часть пропускной способности, выделенной сети хоста, что может снизить общую эффективность рабочей нагрузки ВМ. Ниже приведены рекомендации, которые могут минимизировать негативное влияние виртуализации на пропускную способность vNIC.

Сценарий#

Методы, повышающие производительность сети виртуальной машины:

  • Включение модуля vhost_net:

    1. Убедитесь, что функция ядра vhost_net включена:

      lsmod | grep vhost
      

      Пример вывода команды:

      vhost_net              32768  1
      vhost                  53248  1 vhost_net
      tap                    24576  1 vhost_net
      tun                    57344  6 vhost_net
      

      Если вывод команды выше не содержит никакой информации, то модуль vhost_net выключен.

    2. Включите модуль ядра vhost_net с помощью команды:

      modprobe vhost_net
      
  • Настройка функции multi-queue virtio-net:

    1. Отредактируйте XML-конфигурацию ВМ с помощью команды virsh edit.

    2. Добавьте в раздел <devices> XML-конфигурации следующий блок:

      <interface type='network'>
            <source network='default'/>
            <model type='virtio'/>
            <driver name='vhost' queues='N'/>
      </interface>
      

      В блоке выше замените N на количество vCPU в ВМ. Максимальное количество vCPU – 16.

      Если ВМ запущена, перезапустите ее, чтобы изменения вступили в силу.

  • Объединение сетевых пакетов перед отправкой в ядро. Данный метод может улучшить использование кеша в конфигурациях ВМ Linux с длинным путем передачи.

    Чтобы настроить объединение пакетов, используйте на хосте следующую команду:

    ethtool -C tap0 rx-frames 64
    

    Замените tap0 на имя сетевого интерфейса, который используют ВМ.

  • SR-IOV. Если NIC хоста поддерживает SR-IOV, настройте использование устройств SR-IOV для vNIC. Инструкции приведены в разделе «Управление устройствами SR-IOV».

Инструменты мониторинга производительности виртуальной машины#

Инструменты диагностики производительности помогают определить, что потребляет больше всего ресурсов ВМ и какой аспект производительности ВМ нуждается в оптимизации. Существуют общие инструменты диагностики производительности, предоставляемые ОС, а также предназначенные специально для ВМ.

Общие инструменты мониторинга производительности#

Для общей оценки производительности можно использовать утилиты, предоставляемые по умолчанию ОС хоста и гостевыми ОС:

  • На хосте: утилита top или любое приложение для мониторинга системы.

    Данные инструменты помогают определить какое количество ресурсов хоста потребляют ВМ. Для этого найдите в выходных данных qemu и virt и ознакомьтесь с приведенной в выводе информацией.

    • Если инструмент мониторинга показывает, что какой-либо из процессов qemu или virt потребляет большую часть ЦП хоста или емкости памяти, используйте утилиту perf для исследования. Информация об утилите perf приведена ниже.

    • Если процесс потока vhost_net отображается как потребляющий чрезмерную емкость ЦП хоста, рекомендуется использовать функции оптимизации виртуальной сети, таких как multi-queue virtio-net.

  • В гостевой ОС:

    • в системах Linux – утилита top.

    • в системах Windows – приложение Task Manager.

Примечание

Подробная информация об утилите top приведена в разделе «Утилита top».

Утилиты для виртуальных машин#

  • Утилита perf kvm для сбора и анализа статистики виртуализации.

    1. Установите на хосте пакет perf с помощью команды:

      dnf install perf
      
    2. Используйте следующие команды для отображения статистики производительности хоста виртуализации:

      • Для мониторинга гипервизора в режиме реального времени – perf kvm stat live.

      • Чтобы регистрировать данные perf вашего гипервизора в течение определенного периода времени, активируйте ведение журнала с помощью команды perf kvm stat record. После отмены или прерывания команды данные сохраняются в файле perf.data.guest, который можно проанализировать с помощью команды perf kvm stat report.

    3. Проанализируйте вывод perf для типов событий VM-EXIT и их распределения:

      perf kvm stat report
      

      Пример вывода команды:

      Analyze events for all VMs, all VCPUs:
      
      
                     VM-EXIT    Samples  Samples%     Time%    Min Time    Max Time         Avg time
      
         EXTERNAL_INTERRUPT     365634    31.59%    18.04%      0.42us  58780.59us    204.08us ( +-   0.99% )
                  MSR_WRITE     293428    25.35%     0.13%      0.59us  17873.02us      1.80us ( +-   4.63% )
            PREEMPTION_TIMER     276162    23.86%     0.23%      0.51us  21396.03us      3.38us ( +-   5.19% )
         PAUSE_INSTRUCTION     189375    16.36%    11.75%      0.72us  29655.25us    256.77us ( +-   0.70% )
                        HLT      20440     1.77%    69.83%      0.62us  79319.41us  14134.56us ( +-   0.79% )
                     VMCALL      12426     1.07%     0.03%      1.02us   5416.25us      8.77us ( +-   7.36% )
               EXCEPTION_NMI         27     0.00%     0.00%      0.69us      1.34us      0.98us ( +-   3.50% )
               EPT_MISCONFIG          5     0.00%     0.00%      5.15us     10.85us      7.88us ( +-  11.67% )
      
      Total Samples:1157497, Total events handled time:413728274.66us.
      

      В выводе выше высокий процент событий PAUSE_INSTRUCTION иллюстрирует плохую обработку запущенных vCPU процессором хоста. При хорошем уровне обработки процент таких событий должен быть низким. В данном случае рекомендуется рассмотреть возможность отключения некоторых активных ВМ, удаления виртуальных процессоров с данных ВМ или настройки производительности виртуальных процессоров.

      Другие типы событий, информирующие пользователя о проблемах при выводе perf kvm stat, включают в себя событие INSN_EMULATION, которое предполагает неоптимальную конфигурацию ввода-вывода ВМ.

  • Утилита numastat для получения информации о текущей конфигурации NUMA системы.

    1. Установите пакет numactl, который предоставляет утилиту, с помощью команды:

      dnf install numactl
      
    2. Запустите утилиту с помощью команды:

      numastat -c qemu-kvm
      

      Пример вывода команды:

      Per-node process memory usage (in MBs)
      PID              Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
      ---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
      51722 (qemu-kvm)     68     16    357   6936      2      3    147    598  8128
      51747 (qemu-kvm)    245     11      5     18   5172   2532      1     92  8076
      53736 (qemu-kvm)     62    432   1661    506   4851    136     22    445  8116
      53773 (qemu-kvm)   1393      3      1      2     12      0      0   6702  8114
      ---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
      Total              1769    463   2024   7462  10037   2672    169   7837 32434
      

      В выводе выше показан хост с 4 запущенными ВМ, каждая из которых использует память нескольких узлов NUMA. Данное состояние системы не оптимально и требует корректировки.

      Другой пример вывода команды numastat -c qemu-kvm:

      Per-node process memory usage (in MBs)
      PID              Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
      ---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
      51747 (qemu-kvm)      0      0      7      0   8072      0      1      0  8080
      53736 (qemu-kvm)      0      0      7      0      0      0   8113      0  8120
      53773 (qemu-kvm)      0      0      7      0      0      0      1   8110  8118
      59065 (qemu-kvm)      0      0   8050      0      0      0      0      0  8051
      ---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
      Total                 0      0   8072      0   8072      0   8114   8110 32368
      

      Данный пример вывода демонстрирует, что память предоставляется каждой ВМ одним узлом NUMA, что значительно эффективнее.