13 июля 2021 г.

VMware и NUMA: выбор правильного размера памяти VM

Современные серверные решения на базе архитектуры x86, которые сейчас используются почти во всех программно-аппаратных комплексах, имеют некоторые нюансы. Многопроцессорные сервера, имеющие на материнской плате 2, 4 или даже 8 процессорных сокетов, являются по сути NUMA-архитектурой. NUMA (Non-Uniform Memory Architecture) означает, что каждый процессорный сокет имеет свой пул локальных модулей оперативной памяти и такая связка называется узлом NUMA (рис. 1).

Рис. 1. UMA и NUMA архитектуры.

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

Все современные операционные системы и программные решения более высокого уровня (например, виртуальный гипервизор или СУБД) понимают особенности этой архитектуры. В идеале, это понимание позволяет большинство операций выполнять с памятью локального процессора, не ходя в "дальние края" за памятью соседа. 

vSphere от VMware тоже прекрасно разбирается в NUMA. При конфигурировании виртуальной машины (если вы не активируете опцию "Enable CPU Hot Add") и при её работе гипервизор будет размещать виртуальные процессорные ядра (vCPU) и память виртуальной машины в один узел NUMA. Причём, эта функция работает по умолчанию, ничего отдельно настраивать не надо.

Это всё прекрасно работает для небольших виртуальных машин, которые занимают гораздо меньше памяти, чем имеется в одном узле NUMA. Для работы большого количества таких относительно небольших виртуальных машин на одном сервере решения виртуализации и были прежде всего разработаны. Но у нас немного другой профиль - SAP системы, которые обычно требуют много ресурсов процессора и памяти. 

Хочу на своём примере показать недостаточно корректную настройку размера виртуальных машин, с учётом NUMA архитектуры. На проекте, про который хочу рассказать, были сервера двух типов:

  • 4-х сокетный сервер (8 ядер/16 потоков в каждом процессоре) и 384 Гб оперативной памяти,
  • 2-х сокетный сервер (8 ядер/16 потоков в каждом процессоре) и 256 Гб оперативной памяти.
Таким образом, в сервере первого типа узел NUMA = 16 ядер (с учётом HT) + 96 Гб. 
А в серверах второго типа узел NUMA = 16 ядер (с учётом HT) + 128 Гб памяти. 

Понимая, всю ситуацию с NUMA архитектурой я разместил на серверах первого типа виртуальные машины с характеристиками:

  • 16 vCPU + 192 Гб памяти,
  • 8 vCPU + 96 Гб памяти.
А на серверах второго типа работают виртуальные машины с максимальным размером:
  • 8 vCPU + 96 Гб памяти.
При конфигурировании такой системы я был очень доволен - ведь я точно попал в узлы NUMA. Большая машина идеально вписывается в 2 узла NUMA. А те, что поменьше идеально вписаны в один узел NUMA, как на первых серверах, так и на вторых.

Но после прокачки своих знаний по VMware, мне открылось, что я совершил ошибку при конфигурации объёмов памяти. 

Для мониторинга работы виртуальных машин на узлах ESXi есть команда esxtop (аналог команды top в Linux) (рис. 2). Так вот, для мониторинга работы с памятью и NUMA диагностики, необходимо запустить команду esxtop, нажать "m", перейдя в мониторинг памяти. После этого нажать "f" и добавить к формату вывод статистику по NUMA (рис. 3).

Рис. 2. Основной экран утилиты esxtop.

Рис. 3. Активация просмотра статистики по NUMA узлам.

После этого на экране появится несколько важных полей:

  • NHN - текущий домашний узел для виртуальной машины,
  • NMIG - количество NUMA миграций с узла на узел,
  • NRMEM (MB) - текущее количество "дальней памяти" (из соседней NUMA), используемой виртуальной машиной,
  • NLMEM (MB) - текущее количество локальной памяти, используемой виртуальной машиной,
  • N%L - текущий процент запрошенной виртуальной машиной памяти, являющейся локальной.

Последний параметр помогает проанализировать итог работы виртуальной машины на NUMA узлах. Если он равен 100%, значит производительность оптимальна. Если же ниже 100%, значит не всегда в процессе работы на реальных процессорных ядрах для текущей виртуальной машины идёт попадание в память локального узла NUMA.

По моей ситуации. Первые две большие виртуальные машины не всегда попадают в память локального NUMA узла (рис. 4 и 5). Напомню, что обе машины работают на серверах с размером узла NUMA = 16 ядер (с учётом HT) + 96 Гб.

Рис. 4. Статистика по NUMA виртуальной машины 8 vCPU + 96 Гб.

Рис. 5. Статистика по NUMA виртуальной машины 16 vCPU + 192 Гб.

Процент попадания в локальный NUMA узел 93% и 92% соответственно. Причём, если посмотреть по другим параметрам статистики: виртуальной машине при работе не хватает всего 6-7 Гб памяти на локальном узле. 

"Небольшие" виртуальные машины, работающие на серверах второго типа (с размером узла NUMA = 16 ядер (с учётом HT) + 128 Гб памяти), отлично умещаются в локальных NUMA узлах (рис. 6). Забора "чужой" памяти нет, всё работает оптимально.

Рис. 6. Статистика по NUMA виртуальной машины, работающей на сервере второго типа.

Моя ошибка при конфигурировании размера оперативной памяти больших виртуальных машин в данном случае была в том, что я не учёл накладные расходы гипервизора. Точнее я решил, что накладные расходы общие на весь сервер. А оказалось, что надо учитывать их на каждый узел NUMA. И более оптимально было бы взять не всю память NUMA узла для виртуальной машины, а максимум 90%. Оставив 10% на накладные расходы гипервизора и инфраструктуры VMware.

Максим Мошков рекомендует пользоваться правилом при конфигурировании любых ресурсов в среде VMware - 80% ресурсов можно использовать, а 20% всегда оставлять на запас, накладные расходы и тому подобное.

Если у меня будет возможность, то я переконфигурирую данные виртуальные машины, которые не оптимально попадают в узлы NUMA. И потом поделюсь с вами результатами статистики.

Update: результаты оптимизации можно найти в этом посте.

Автор: Шиболов Вячеслав Анатольевич

 

1 комментарий:

  1. Анонимный23.05.2022, 11:44

    Спасибо, очень доволен что поал этот пост

    ОтветитьУдалить