- Настройки виртуальных процессоров в Hyper-V
- Virtual Machine Reserve
- Virtual Machine Limit
- Relative Weight
- Управление числом vCPU и ядер в виртуальной машине
- Виртуальная машина Windows 10 не видит все ядра
- Количество поддерживаемых процессоров в Windows 10
- Управление виртуальными ядрами и vCPU в KVM
- Настройка виртуальных процессоров и количества ядер в VMWare
- Архитектура NUMA и виртуальные vCPU
Настройки виртуальных процессоров в Hyper-V
В этой статье я расскажу о «продвинутых» настройках процессоров виртуальных машин в Hyper-V. Наверняка все эти настройки видели, но мало кто реально пробовал их менять, и еще меньше – знают, для чего они реально нужны и как они работают.
Для примера будем рассматривать некий абстрактный сервер с четырьмя процессорными ядрами. Так же, все виртуальные машины по умолчанию конфигурируются с четырьмя виртуальными процессорами.
Вот они, эти настройки:
Virtual Machine Reserve
Этот параметр означает, что определенный процент ресурсов будет жестко зарезервирован за виртуальной машиной. По умолчанию равен 0%. В первую очередь этот параметр играет роль в ситуации «борьбы за ресурсы» (то есть когда физические процессоры используются на 100%, а виртуальным машинам требуется еще). В этой ситуации те из виртуальных машин, у которых задан этот параметр, гарантированно получат как минимум то, что за ними зарезервировано.
Работает этот параметр следующим образом. Возьмем наш 4-ядерный сервер и 5 виртуальных машин, по 4 виртуальных процессора на каждой. Если установить Virtual Machine Reserve, равный 20%, то от физически имеющихся ресурсов для каждой виртуальной машины будет зарезервировано 0,2 * 4 / 4 = 20%. Это значение отобразиться в поле «Percent of total system resources». Если у сервера будет 8 ядер, то это значение будет уже другое: 0,2 * 4 / 8 = 10%.
Но вернемся к нашим баранам. Если мы запустим все 5 наших виртуальных машин, то все процессорные ресурсы будут заняты, и запустить 6ю виртуальную машину будет можно только в том случае, если Virtual Machine Reserve установлен равным 0%:
А вот теперь более интересный пример. На той же самой 4-ядерной системе создадим две виртуальных машины. Одной из них назначим 4 виртуальных процессора, и установим Virtual Machine Reserve 50%. Это значит, что наша виртуальная машина получает половину от каждого из имеющихся ядер, половину от всех системных ресурсов сервера. Запустим ее. Второй виртуальной машине дадим два виртуальных процессора и Virtual Machine Reserve 80%. Это – 40% от всех системных ресурсов. Казалось бы, 50% + 40% = 90%. То есть вторая виртуальная машина тоже должна запуститься, но на самом деле она не запустится. А все потому, что система попытается найти два ядра, от которых можно «отщипнуть» в резерв 80%, а все 4 ядра зарезервированы на 50% каждое:
Об этом ограничении нужно всегда помнить, и не «играться» с параметром Virtual Machine Reserve без насущной необходимости. Особое внимание нужно уделять при использовании кластерных решений: при сбое одного узла возможна ситуация, что часть виртуальных машин не сможет перезапуститься на доступном узле из-за недостатка ресурсов для резервирования.
Тем не менее, резервирование здесь не совсем «жесткое». Допустим, в примере с 5ю виртуальными машинами и 20% Virtual Machine Reserve все 5 виртуальных машин простаивают. Если вдруг одной из виртуальных машин потребуется больше, чем 20% доступных ресурсов – эти ресурсы будут ей предоставлены, не смотря на то, что все 100% вроде бы как зарезервированы. Дело в том, что процессорный ресурс может легко выделяться виртуальным машинам, и так же легко у них забираться. Так что, если возникнет необходимость – резервы для всех гарантируются.
Для чего можно использовать этот параметр? Главное его назначение – гарантировать ресурсы для бизнес-критичных виртуальных машин, имеющих жесткое SLA. Кроме этого, его можно использовать для искусственного ограничения на количество одновременно запущенных виртуальных машин, хотя по моему мнению – это не самое красивое решение.
Virtual Machine Limit
Этот параметр, как и предыдущий (Virtual Machine Reserve), задается в процентах от доступных виртуальной машине ресурсов. Точно так же, как и предыдущий параметр – есть поле «Percent of total system resources» — все точно так же. По умолчанию равен 0, что означает, что никаких ограничений нет, и виртуальная машина может забирать себе столько процессорных ресурсов, сколько ей необходимо и сколько доступно физически. Ненулевое значение параметра Virtual Machine Limit означает, что виртуальная машина ни при каких условиях не сможет использовать больше процессорных ресурсов, чем разрешено. Единственное применение этого параметра – ограничить «аппетит» виртуальной машины, если используются приложения, которые слишком сильно нагружают процессор.
Так же, как и Virtual Machine Reserve, лимит применяется отдельно к каждому виртуальному процессору. К примеру, если виртуальная машина сконфигурирована с 2 процессорами и установлен лимит 50% — то она получит два виртуальных процессора, каждый из которых ограничивается 50%.
Но есть одно небольшое отличие: лимит задается жестко. Если Virtual Machine Limit равен 50% — виртуальная машина никогда не сможет использовать больше, даже если на сервере больше ничего не запущено. Кроме этого, лимит применяется отдельно к каждому виртуальному процессору. К примеру, если виртуальная машина сконфигурирована с 2 процессорами и установлен лимит 50% — то она получит два виртуальных процессора, каждый из которых лимитирован 50%.
Relative Weight
Третий параметр, о котором я хотел бы рассказать – Relative Weight. В отличие от предыдущих этот параметр – безразмерная величина, и может изменяться от 0 до 10000. По умолчанию равен 100.
До тех пор, пока у сервера имеются свободные системные ресурсы – параметр Relative Weight не проявляет себя абсолютно никак. Будь значение веса хоть 100, хоть 200, хоть 10000 – на работе виртуальных машин это не отразится. Но как только виртуальные машины начинают запрашивать больше процессорных ресурсов, чем сервер готов предоставить физически – тут-то и начинается самое интересное. Если у всех виртуальных машин значение этого параметра одинаково (к примеру, у всех 100) – то каждая из них получит равную долю процессорного ресура. А вот если у одной или нескольких виртуальных машин Relative Weight выше – это значит, что они «равнее, чем другие», и они получат больше процессорного ресурса, чем остальные. А если есть виртуальные машины с еще более высокими значениями этого параметра – то они получат еще больше. Этот параметр хорош тем, что позволяет выделять более критичные виртуальные машины, при этом не боясь, что какая-то из виртуальных машин откажется запускаться, и придется менять настройки еще и для нее. Но есть один небольшой нюанс: Relative Weight вовсе не дает гарантий, что виртуальная машина в трудную минуту получит ровно столько процессорных ресурсов, сколько ей нужно. Если какие-то из виртуальных машин являются особо критичными, и на них распространяются жесткие SLA – лучше использовать Virtual Machine Reserve, который гарантирует выделение ресурсов.
Если систему обслуживают несколько администраторов – то необходимо договориться о единой шкале для параметра Relative Weight. В частности, если один будет ставить для некритичныхвиртуальных машин значение 100, для критичных 200, а другой будет ставить 500 для некритичных и 1000 для критичных – система может повести себя немного непредсказуемо. Но это уже вопрос стандартизации, и в более-менее сложных системах, которые управляются более чем одним администратором – такие договоренности должны быть a priori.
Управление числом vCPU и ядер в виртуальной машине
При создании виртуальных машин на различных гипервизорах (VMWare, KVM, Hyper-V и т.д.) вы можете обратить внимание, что иногда виртуальная машина может не видеть все выделенные ей виртуальные ядра (vCPU). В нашем случае виртуальной машине на KVM были выделены 8 vCPU, на нее установлена Windows 10. Однако Windows определяла эти ядра как отдельные процессоры, из которых можно использовать только 2 vCPU.
Виртуальная машина Windows 10 не видит все ядра
Если открыть диспетчер устройств Windows, можно убедится, что все выделенные ядра видны в качестве 8 отдельных виртуальных процессоров типа QEMU Virtual CPU version 2,5.
При этом в свойствах Windows 10 (Computer -> Properties) и в Task Manage видно, что на компьютере доступны только 2 процессора QEMU Virtual CPU.
То есть сколько бы вы не добавили виртуальных ядер, Windows 10 все равно сможет использовать только два. При этом соседний виртуальный сервер с Window Server 2016 на этом же гипервизоре видит все 16 выделенных ему vCPU.
Количество поддерживаемых процессоров в Windows 10
Проблема заключается в том, что в десктопных редакциях Windows (Windows 10/8.1/7) есть ограничение на максимальное количество физических процессоров (сокетов), которое компьютер может использовать:
- Windows 10 Home – 1 CPU
- Windows 10 Professional – 2 CPU
- Windows 10 Workstation – до 4 CPU
- Windows Server 2016 – до 64 CPU
Однако это ограничение не распространяется на ядра. Т.е. для повышения производительности вы можете использовать процессор с большим количеством ядер. Большинство гипервизоров умеют предоставлять vCPU в виде процессоров, процессорных ядер или даже потоков. Т.е. вместо 8 виртуальных CPU вы можете предоставить vCPU в виде 2 сокетов по 4 ядра в каждом. Рассмотрим, как в различных системах виртуализации выделить виртуальные процессоры в виде ядер и как это связать с архитектурой NUMA, использующейся в современных процессорах.
Управление виртуальными ядрами и vCPU в KVM
В моей виртуальной машине KVM c Windows 10, все назначенные виртуальные ядра считаются отдельными процессорами.
Чтобы использовать все ресурсы CPU, выделенные виртуальной машине нужно, чтобы виртуальная машина видела не 8 процессоров, а один 8-ядерный процессор, 2 процессора по 4 ядра или 1 процессор с 4 ядрами по 2 потока. Попробуем изменить способ назначения виртуальных ядер для ВМ на KVM.
Выключите виртуальную машину:
# virsh shutdown server.vpn.ru – где server.vpn.ru это имя виртуальной машины.
Выведите текущую XML конфигурацию виртуальной машины KVM:
# virsh dumpxml server.vpn.ru
Нам интересен блок с описанием процессоров:
Как видим, у нас указано просто 8 vCPU. Изменим конфигурацию:
# virsh edit server.vpn.ru
И после добавим:
- host-passthrough — режим эмуляции при котором на виртуальной машине будет показан физический процессор узла кластера (ноды).
- sockets=’1′ — указываем что процессор 1
- cores=’4′ — указываем, что процессор имеет 4 ядра
- threads=’2′ — указываем, что ядра у нас по 2 потока
Сохраните конфигурационный файл и запустите ВМ. Авторизуйтесь в гостевой ВМ с Windows 10 и в Task Manager или Resource Monitor проверьте, что ОС видит все выделенные виртуальные ядра.
Также в свойства системы теперь стал отображаться физический процессор хоста Intel(R) Xeon(R) Silver 4114 CPU, а не виртуальный.
Так нам удалось решить проблему с нагрузкой на ВМ, так как двух ядер не хватало для полноценной работы приложений.
Настройка виртуальных процессоров и количества ядер в VMWare
Вы можете изменить способ презентации vCPU для виртуальной машины VMWare из интерфейса vSphere Client.
- Выключите ВМ и откройте ее настройки;
- Разверните секцию CPU;
- Изменим конфигурацию ВМ так, чтобы гостевая ОС видела 2 процессора по 4 ядра. Измените значение Cores per Socket на 4. Это означает, что гостевая ОС будет видеть два четырех –ядерных процессора (2 сокета по 4 ядра);
- Сохраните изменения и запустите ВМ.
Архитектура NUMA и виртуальные vCPU
Есть еще несколько аспектов назначения vCPU и ядер виртуальным машинам, которые нужно понимать.
При назначении ядер на сокете учитывайте наличие NUMA архитектуры (используется в большинстве современных CPU). Не рекомендуется назначать вашей ВМ количество ядер на сокет (и общее количество vCPU) больше, чем доступно ядер на вашем физическом сокете/процессоре (ноде NUMA). При размещении на одной физической ноде NUMA, виртуальная машина сможет использовать быструю локальную RAM, доступную на конкретной ноде NUMA. Иначе для выполнения операции процессам придется ждать ответа от другой ноды NUMA (что несколько более долго).
Если вы назначаете для ВМ два отдельных виртуальных сокета, то гипервизор может их запускать на разных нодах NUMA. Что не лучшим образом скажется на производительности ВМ.
Если количество требуемых vCPU превышает количество ядер на 1 физическом сокете (ноде NUMA), нужно создать несколько виртуальных сокетов (процессоров) с необходимым количество ядер. Также не желательно использовать нечетное количество процессоров (лучше добавить 1 vCPU)
Это позволит сохранить производительность виртуальной машины.
Например, для 2 процессорного хоста с 10 ядрами (суммарно доступно 40 vCPU с учетом Hyper—Threading), при настройке vCPU для ВМ оптимально использовать такие конфигурации:
Требуемое количество vCPU | Количество виртуальных сокетов в настройках ВМ | Количество ядер на виртуальном процессоре в настройках ВМ |
1 | 1 | 1 |
…… | ||
10 | 1 | 10 |
11 | Не оптимально | |
12 | 2 | 6 |
…… | ||
20 | 2 | 10 |
Например, ВМ с Microsoft SQL Server 2016 Enterprise Edition 16 vCPU в конфигурации 8 сокетов по 2 ядра будет работать хуже, чем в конфигурации 2 сокета по 8 ядер.
Также не забывайте, что некоторые приложения лицензируются по физическим сокетам (так было в старых версиях SQL Server). Иногда вам просто выгоднее лицензировать один многоядерный процессор, чем несколько процессоров с меньшим количеством ядер.