В ПК СВ "Брест" топология виртуальной машины определяется количеством сокетов, ядер и потоков. Мы предполагаем, что узел или ячейка NUMA эквивалентны сокету, и в этом руководстве они будут использоваться взаимозаменяемо.

Общие сведения

В современных многопроцессорных системах, вместо подключения отдельных процессоров к плате, разработчики стали объединять ядра процессоров в один модуль, и вместо предоставления равноправного доступа к памяти была разработана стратегия неравномерного доступа NUMA (Non-Uniform Memory Access "неравномерный доступ к памяти" или Non-Uniform Memory Architecture "архитектура с неравномерной памятью"). В этой схеме реализации время доступа к компьютерной памяти определяется её расположением по отношению к процессору.
Схема функционирования представлена на рисунке:

Каждый процессор архитектуры NUMA может получить доступ к своей собственной памяти и памяти других процессоров. Доступ к своей собственной памяти намного быстрее, чем доступ к другой памяти, с разницей в скорости в 10-100 раз. Поэтому целью настройки NUMA является предоставление процессору максимально возможного доступа к собственной памяти для повышения скорости доступа.

ПК СВ "Брест" позволяет развертывать ВМ с настроенной топологией NUMA, что повышает производительность и безопасность. 

Отличия базовой и NUMA топологии

В базовой топологии определяется только количество vCPU (виртуальных ЦП) и объем памяти ВМ. В этом случае гостевая ОС видит vCPU соответствующие одному ядру и одному потоку каждый. Например шаблон для ВМ с четырьмя vCPU будет выглядеть так:

MEMORY = 1024
VCPU   = 4
CODE

ВМ, работающая с этой конфигурацией, будет видеть следующую топологию:

# lscpu
...
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             4
NUMA node(s):          1

# numactl -H
available: 1 nodes (0)
node 0 cpus: 0 1 2 3
node 0 size: 1023 MB
node 0 free: 607 MB
node distances:
node   0
  0:  10
CODE

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

VCPU   = 8
MEMORY = 1024

TOPOLOGY = [ SOCKETS = 2, CORES = 2, THREADS = 2 ]
CODE

ВМ, работающая с такой конфигурацией, будет видеть топологию:

# lscpu
...
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             2
NUMA node(s):          1
...

# numactl -H
available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 1023 MB
node 0 free: 600 MB
node distances:
node   0
  0:  10
CODE

Топология NUMA позволяет закрепить размещение узлов NUMA ВМ в узлах NUMA сервера виртуализации. В этой конфигурации каждый сокет будет доступен гостевой ОС как отдельный узел NUMA со своей собственной локальной памятью.

В предыдущем примере можно предоставить два сокета (узла NUMA), настроив политику закрепления PIN_POLICY (см. Политика закрепления):

VCPU   = 8
MEMORY = 1024

TOPOLOGY = [ PIN_POLICY = thread, SOCKETS = 2, CORES = 2, THREADS = 2 ]
CODE

ПК СВ сгенерирует запись для каждого узла NUMA, расширяя предыдущий шаблон виртуальной машины:

NUMA_NODE = [    MEMORY=512,TOTAL_CPUS = 4 ]
NUMA_NODE = [ MEMORY = 512, TOTAL_CPUS = 4 ]
CODE

Тогда гостевая ВМ будет видеть следующую топологию:

# lscpu
...
CPU(s):                8
-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             2
 NUMAnode(s):          2
...

# 
available: 2 nodes  (0-1)
node 0 cpus: 0 1 2 3
node  0size0 : 511
node 0 0: : 235
node 1 1: : 4 5 6
7 1 size1: 511 MB
node 1 free: 359 MB
node distances:
node   0   1
  0:  10  20
  1:  20  10
CODE

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

MEMORY = 3072
VCPU = 6
CPU  = 6
TOPOLOGY = [ PIN_POLICY = CORE, SOCKETS = 2 ]

NUMA_NODE = [ MEMORY = 1024, TOTAL_CPUS = 2 ]
NUMA_NODE = [ MEMORY = 2048, TOTAL_CPUS = 4 ]
CODE

Политика закрепления

При настройке топологии NUMA в гостевых ВМ, для сопоставления ресурсов каждого виртуального узла NUMA (память и vCPU) с узлами сервера виртуализации, нужно установить политику закрепления. ПК СВ "Брест" позволяет работать с четырьмя различными политиками:

Политика закрепления

Обозначение в веб-интерфейсе
(Политика Pin-кода)

Принцип взаимодействия
COREядрокаждый vCPU назначается целому ядру сервера виртуализации. Никакие другие потоки в этом ядре использоваться не будут. Эта политика может быть полезна для изоляции рабочей нагрузки ВМ по соображениям безопасности.
THREADпотоккаждый vCPU назначается потоку процессора сервера виртуализации
SHAREDобщийвиртуальная машина назначается набору ЦП сервера виртуализации, совместно используемому всеми виртуальными ЦП ВМ.
NONEникакойВМ не назначена ни одному процессору сервера виртуализации. Доступ к ресурсам (т.е. процессорное время) будет ограничен атрибутом — CPU.

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

При использовании политики закрепления рекомендуется фиксировать только количество vCPU, позволяя планировщику выбирать количество ядер и потоков в топологии. ПК СВ по умолчанию оптимизирует производительность ВМ, выбрав потоки для каждого ядра в соответствии со следующим:

  • Для CORE политики закрепления значение параметра THREADS установлено равным 1;

  • Предпочтительна конфигурация оборудования, максимально приближенная к конфигурации сервера виртуализации;

  • Количество потоков на ядро не будет превышать количество потоков сервера виртуализации;

  • Предпочтительной является конфигурация с наибольшим количеством потоков / ядер, которое умещается на сервере виртуализации.

Когда значение THREADS установлено, ПК СВ будет искать сервер виртуализации, который может выделить указанное количество потоков на ядро. Если такой не будет найден, то ВМ останется в состоянии Ожидание. Это может потребоваться, если необходимо установить фиксированное количество потоков на ядро для ВМ.

Сквозной доступ к устройствам PCI

Процесс планирования немного изменяется, когда закрепленная ВМ использует устройства для передачи данных через шину PCI. В этом случае узлы NUMA, к которым подключены устройства PCI, имеют приоритет для закрепления vCPU виртуальной машины и памяти для ускорения операций ввода-вывода. Дополнительная настройка не требуется.

Использование HugePages (огромных страниц)

Системы с большим объемом физической памяти используют большое количество страниц виртуальной памяти. Это сильно снижает эффективность использования кэшей преобразования из виртуальной в физическую память. Использование HugePages сокращает количество виртуальных страниц в системе и оптимизирует подсистему виртуальной памяти.

Чтобы разрешить использование HugePages для выделения памяти ВМ, необходимо установить значение размера страниц в параметре HUGEPAGE_SIZE. Размер должен быть указан в мегабайтах. Например, для использования 2 МБ HugePages значение параметра будет выглядеть так:

TOPOLOGY = [ HUGEPAGE_SIZE = 2 ]
CODE

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

Описание параметров топологии NUMA

ПараметрОбозначение параметра в веб-интерфейсеОписание
PIN_POLICYПолитика Pin-кодаустановленная политика закрепления (см. Политика закрепления)
SOCKETSСокетыколичество сокетов или узлов NUMA
CORESЯдраколичество ядер на узел
THREADSПотокиколичество поток на ядро
HUGEPAGE_SIZEРазмер огромных страниц (hugepages)размер HugePages в МБ. Если параметр не определен, то HugePages использоваться не будут
MEMORY_ACCESSДоступ к памятиопределяет отображение памяти как общий каталог или private

Настройка сервера виртуализации

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

Необходимо определить, какие узлы серверов виртуализации будут использоваться для запуска закрепленных рабочих нагрузок, и определить значение PIN_POLICY  с помощью команды onehost update или через веб-интерфейс. Узел может работать в двух режимах:

  • NONE (в веб-интерфейсе Отсутствует)— режим по умолчанию, в котором не учитывается топология NUMA или аппаратные характеристики. Ресурсы назначаются и балансируются внешним компонентом, например numad или ядром;

  • PINNED (в веб-интерфейсе Запаролен) — ВМ выделяются и закрепляются на определенных узлах в соответствии с различными политиками.

ПК СВ "Брест" позволяет создать кластер, включающий все узлы серверов виртуализации, предназначенные для выполнения закрепленных рабочих нагрузок, и установить PIN_POLICY на уровне кластера.

С помощью команды onehost show можно проверить настройки топологии NUMA в ВМ. Пример вывода для сервера виртуализации с четырьмя ядрами и двумя потоками и запущенной ВМ с двумя vCPU:

$ onehost show 0 ... MONITORING INFORMATION PIN_POLICY="PINNED" ... NUMA NODES ID CORES USED FREE 0 X- X- -- -- 4 4 NUMA MEMORY NODE_ID TOTAL USED_REAL USED_ALLOCATED FREE  0 7.6G 6.8G 1024M 845.1M 
CODE

где "X- X- -- --"отображает распределение NUMA. Каждая группа соответствует ядру, и когда поток свободен, он отображается как "-"; "x" означает, что поток используется и "X" означает, что поток используется и в ядре нет свободных потоков. 

В этом примере в ВМ установлена CORE политика закрепления.

Вы также можете изолировать некоторые ЦП узла сервера виртуализации от планировщика NUMA. Изолированные процессоры не будут использоваться для закрепления какой-либо ВМ. Изолированные процессоры определяются значением параметра ISOLCPUS или через веб-интерфейс. Значение параметра задается разделенным запятыми списком идентификаторов ЦП. Например при ISOLCPUS="0,5" будут изолированы процессоры 0,5 и, следовательно, не будут использоваться для закрепления какой-либо ВМ.

Политика закрепления и избыточная нагрузка (overcommitment)

При использовании политики закрепления избыточная нагрузка по умолчанию отключена (CPU = 1 в шаблоне ВМ). Однако в некоторых конфигурациях может потребоваться настроить поток процессора, в котором запущена ВМ, при этом позволяя запускать больше виртуальных машин в том же потоке процессора.

Вы можете настроить количество виртуальных машин на физический поток для каждого сервера виртуализации, установив значение параметра VMS_THREAD (по умолчанию равно 1) в шаблоне. Например, при установленном значении параметра VMS_THREAD = 4 ПК СВ будет закреплять до четырех ВМ на физический поток в каждом ядре.

При использовании избыточной нагрузки и топологии NUMA необходимо установить избыточную нагрузку сервера виртуализации так, чтобы общее количество процессоров учитывало новое значение параметра VMS_THREAD. Например, в сервере виртуализации с восемью ЦП (TOTAL_CPU=800) и VMS_THREAD=4 необходимо переопределить номер процессора, чтобы значение параметра TOTAL_CPU было не более 3200 (8 * 4 = 32 ЦП). Для этого нужно установить значение параметра RESERVED_CPU, в данном случае оно будет равным -2400 (3200 = 800 - (-2400).

Ограничения при использовании топологии NUMA

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

  • ВМ с закрепленной топологией не поддерживают живую миграцию;

  • Изменение размеров параметров в топологии NUMA не поддерживается, т.к. узлы NUMA повторно генерируются с новым vCPU и памятью. Также стоит отметить, что закрепленные ЦП могут меняться;

  • При закрепленной ассиметричной конфигурации и использовании qemu 4.0 и libvirt 5.4 узлы NUMA не могут быть определены без памяти или без какого-либо процессора, о чем будут свидетельствовать следующие ошибки:

    error: Failed  tocreate domain from deployment.0
    error: internal error: process exited while connecting to monitor:  qemu-system-x86_64: -object memory-backend-ram,id=ram-node1,size=0,host-nodes     
    
      
    =0,policy=bind:property'size'ofmemory-backend-ramdoesn't take value '0'virshcreatedeployment.0error: Failed  tocreate domain from deployment.0
    error: XML     error:Missing'cpus'attributein NUMA cell
    CODE

Настройка виртуальной топологии NUMA для ВМ

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

Примеры способов настройки ВМ с ролью сервера виртуализации с 6 логическими процессорами и 16 ГБ оперативной памяти, распределенными между 2 узлами NUMA:

  1. Создать новую ВМ с помощью утилиты virt-install.

    1. В параметре --cpu указать:

      --cpu host-passthrough,cache.mode=passthrough,cell0.memory=8388608,cell0.cpus=0-2,cell1.memory=8388608,cell1.cpus=3-5
      где

      • cell<N>.memory - количество оперативной памяти для узла NUMA в КБ;
      • cell<N>.cpus - список процессоров, которые будут назначены узлу NUMA;
      • <N> - номер узла NUMA.

      По умолчанию ВМ будет создана с распределением всей оперативной памяти и процессоров в один узел NUMA.

    2. Проверить конфигурацию ВМ командой virsh dumpxml. Пример вывода для указанной конфигурации:

       <memory unit='KiB'>16777216</memory>
       <currentMemory unit='KiB'>16777216</currentMemory>
       <vcpu placement='static'>8</vcpu>
       <os>
       <type arch='x86_64' machine='pc-q35-rhel7.6.0'>hvm</type>
       </os>
       <features>
       <acpi/>
       <apic/>
       </features>
       <cpu mode='host-passthrough' check='none'>
       <cache mode='passthrough'/>
       <numa>
       <cell id='0' cpus='0-2' memory='8388608' unit='KiB'/>
       <cell id='1' cpus='3-5' memory='8388608' unit='KiB'/>
       </numa>
       </cpu>
      CODE
    3. После установки ОС на ВМ проверить настроенные узлы NUMA командой:

      numactl -H
      Пример вывода:

      available: 2 nodes (0-1)
      node 0 cpus: 0 1 2
      node 0 size: 7964 MB
      node 0 free: 6801 MB
      node 1 cpus: 3 4 5
      node 1 size: 8062 MB
      node 1 free: 6975 MB
      node distances:
      node   0   1 
        0:  10  20 
        1:  20  10 
      CODE
  2. Настроить шаблон созданной ВМ

    1. Открыть шаблон ВМ командой:

      virsh edit <идентификатор_вм>

    2. В открывшемся шаблоне ВМ отредактировать параметр cpu и привести его к виду:

       <cpu mode='host-passthrough' check='none'>
       <cache mode='passthrough'/>
       <numa>
       <cell id='0' cpus='0-2' memory='8388608' unit='KiB'/>
       <cell id='1' cpus='3-5' memory='8388608' unit='KiB'/>
       </numa>
       </cpu> 
      CODE

      где

      • cell id - номер узла NUMA;

      • cpus - список процессоров, которые будут назначены узлу NUMA;
      • memory - количество оперативной памяти для узла NUMA в КБ.
    3. Выключить ВМ и сохранить шаблон.

    4. В ОС ВМ проверить настроенные узлы NUMA командой:

      numactl -H
      Пример вывода:

      available: 2 nodes (0-1)
      node 0 cpus: 0 1 2
      node 0 size: 7964 MB
      node 0 free: 6801 MB
      node 1 cpus: 3 4 5
      node 1 size: 8062 MB
      node 1 free: 6975 MB
      node distances:
      node   0   1 
        0:  10  20 
        1:  20  10 
      CODE

Пример настройки топологии NUMA в веб-интерфейсе ПК СВ "Брест"

  1. В веб-интерфейсе ПК СВ "Брест" в меню слева выбрать пункт меню Инфраструктура — Узлы и на открывшейся странице Узлы выбрать созданный ранее узел (в данном примере fn.brest.local). Откроется страница Узел.

  2. На странице Узел перейти на вкладку NUMA. В выпадающем списке Политика PIN-кода выбрать значение Запаролен.
  3. На странице Узел нажать на кнопку Вернуться к списку.
  4. В веб-интерфейсе в меню слева выбрать пункт меню Шаблоны — ВМ и на открывшейся странице Шаблоны ВМ выбрать созданный ранее шаблон (в данном примере virtm). Откроется страница Шаблон ВМ.

  5. На странице Шаблон ВМ нажать на кнопку Обновить.

  6. На открывшейся станице Изменить шаблон ВМ перейти на вкладку NUMA и установить флаг Топология NUMA. Появятся параметры NUMA с возможностью редактирования.

  7. На странице Изменить шаблон ВМ на вкладке NUMA
    1. в выпадающем списке Политика Pin-кода выбрать значение поток;
    2. указать основные параметры NUMA.
  8. На странице Изменить шаблон ВМ нажать кнопку Обновить.
  9. Создать новую гостевую ВМ из отредактированного шаблона (см. Создание предварительного шаблона и установка ОС в ВМ).
  10. В веб-интерфейсе в меню слева выбрать пункт меню Экземпляры ВМ — ВМ и дождаться пока в столбце Статус на странице ВМ для созданной на предыдущем шаге ВМ значение Инициализация не изменится на ВЫКЛЮЧЕНО (промежуточные значения: Ожидание и Пролог). Для обновления информации, отображаемой на странице, можно воспользоваться кнопкой Обновить.
  11. В ОС сервера управления проверить результат настройки NUMA командой:

    sudo onevm show <идентификатор_ВМ> | grep -iE "(NUMA|CORES|2)"
     где <идентификатор_ВМ> - наименование созданной ВМ
    В выводе должны отобразиться установленные значения:

    NUMA NODES
                    1024M          1
                    1024M          1
     CORES  SOCKETS  THREADS
         0        2        1
    CODE


  12. Запустить созданную гостевую ВМ.

    Действия, описываемые далее, выполняются в ОС гостевой ВМ под учетной записью администратора.

  13. В ОС гостевой ВМ установить пакет numactl командой:

    sudo apt install numactl

    Пакет numactl доступен в старших версиях AL SE, начиная с очередного обновления 1.7.

  14. Проверить список доступных узлов командой:

    sudo numactl -H
    Пример вывода:

    node distances: 
    node 0 1
    0: 10 20 
    1: 20 10 
    CODE