KVM. Оптимизация работы с памятью при помощи Hugepages

01/20/2016

Чтобы виртуальные машины, запущенные в Linux с использованием гипервизора KVM, могли размещать свою оперативную память в физической памяти хоста, размеченной при помощи Hugepages, ядро Linux хоста должно быть собрано с поддержкой Hugepages, механизм Hugepages должен быть активирован и, наконец, KVM должен быть настроен на использование Hugepages. Только сочетая эти 3-х пункта, вы сможете получить реальную поддержку Hugepages и профит от её использования.

Проверка поддержки Hugepages ядром Linux

С первым пунктов всё просто - скорее всего ваш дистрибьютор уже позаботился о поддержке Hugepages, проверть это можно, введя в терминале

gunzip -c /proc/config.gz | grep HUGETLB

Если команда не сработает, выдав "No such file or directory" или что-то похожее, связанное с отсутствием файла конфигурации, с которым ядро было собрано, можно попробовать поискать его в /boot>/p>

grep HUGETLB /boot/config-`uname -r`

Такое различие связано с методами построения дистрибутива и не влияет на конечный результат. Итак, получив наконец список параметров, следует убедиться, что для "CONFIG_HUGETLBFS" и "CONFIG_HUGETLB_PAGE" после знака "=" стоит буква "y", означающая готовность ядра Linux работать с Hugepages - это настройка по умолчанию в большинстве дистрибутивов. Если же нет, то дальше путь закрыт и "Добро пожаловать в клуб любителей пересобирать ядро Linux"

Включение Hugepages в Linux

Переходим ко второму пункту - активации механизма Hugepages в Linux. Этот этап делится на 2: выделение памяти под Hugepages и монтировании специальной файловой системы hugetlbfs - интерфейса взаимодействия программ с Hugepages.

Чтобы выделить определенное количество памяти под Hugepages, следует отредактировать файл sysctl.conf - файл, содержащий параметры ядра. В одних системах, таких как Debian версии 7-8 и Ubuntu версии 12.04 он располагается в /etc (/etc/sysctl.conf), в новых системах, таких как arch linux, в /etc вы его не найдете. Его, если нет, следует создать в /etc/sysctl.d/ под именем, например, hugepages.conf. Разобравшись с sysctl, добавляем (или изменяем) следующую строчку

vm.nr_hugepages = 2048

где 2048 указывает ядру на то, сколько страниц памяти следует выделить для Hugepages. Посчитать этот пораметр не сложно. Предположим нам нужно запустить виртуальную машину, отдав ей 4 гигабайта. 4 гигабайта = 4096 мегабайт. 4096 мегабайт / 2 мегабайта на страницу (размер одной hugepage) = 2048 страниц. Это число следует указать после знака "=" для параметра "vm.nr_hugepages". Если вам потом потребуется дать виртуалке больше памяти, или запустить новую виртуалку, нужно будет количество страниц увеличивать. Само собой, объем памяти должен быть достаточным для проведения этой операции. Помните, что память, отданная под Hugepages, уже не сможет быть использована обычными программами, которые поддержки Hugepages лишены. И после каждого изменения этого параметра, вам следует перезагружать систему.

Есть вариант изменения количества Hugepages без перезагрузки. Для этого следует ввести команду

echo 2048 > /proc/sys/vm/nr_hugepages

После нажатие клавиши "Enter" ядро попытается аллоцировать 2048 больших страниц памяти, и, если количества свободной физической памяти будет достаточно, всё пройдет хорошо. Но только изменение параметра "vm.nr_hugepages" в sysctl.conf является перманентным (сохранится после перезагрузки), поэтому мы рекомендуем первый метод.

Проверить, что ядро зарезервировало необходимое количество страниц можно командой

cat /proc/meminfo | grep Huge

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

Следующим шагом мы должны смонтировать специальную файловую систему hugetlbfs - интерфейс взаимодействия программ с Higepages. Для начала проверьте, не смонтирована ли она уже, дистрибьютор мог и об этом позаботиться:

mount | grep huge

Если вывод непустой (в Debian версии 8 и выше эта настройка по-умолчанию) и содержит запись с указанием того, куда смонтирована hugetlbfs - данный шаг можно смело пропускать. Если нет, монтируем ФС вручную:

mount -t hugetlbfs hugetlbfs /hugepages

Само собой точка монтирования - папка /hugepages, должна существовать. А чтобы hugetlbfs монтировалась автоматически при каждой загрузке, в системах на базе init, следует добавить запись в файл /etc/fstab вида

hugetlbfs /hugepages hugetlbfs defaults 0 0

Если ваша система построена на базе SystemD, вам следует создать unit-файл типа mount следующего содержания

[Unit]
Description=Huge Pages File System
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/sys/kernel/mm/hugepages
ConditionCapability=CAP_SYS_ADMIN
 
[Mount]
What=hugetlbfs
Where=/hugepages
Type=hugetlbfs

Назвать его hugepages.mount (суффикс .mount обязателен) и положить в /lib/systemd/system/

Настрока KVM для работы с Hugepages

Теперь, когда все подготовительные этапы завершены: вы убедились, что ядро поддерживает Hugepages, вы посчитали необходимое количество Hugepages и передали их в качестве параметра ядру Linux, смонтировали специальную файловую систему hugetlbfs - можно приступать к настройке KVM для работы с Hugepages. На самом деле настраивать KVM-то и не нужно, нужно всего лишь немного изменить конфигурацию виртуальной машины. Если вы используете для работы с KVM библиотеку libvirt и такие программы как графический virt-manager или консольный virsh, вам следует выполнить в консоли

virsh list

что позволит узнать ID интересующей вас виртуальной машины. А потом, с помощью команды

virsh stop VIRTUAL_MACHINE_ID

остановить виртуальную машину. Перезапустить libvirt

systemctl restart libvirtd.service

И, наконец, отредактировать конфигурационный файл виртуальной машины с помощью команды

virsh edit VIRTUAL_MACHINE_NAME

Добавить в начало файла (чуть дальше от начала, где-то после строк относящихся к memory) следующие строки

<memoryBacking>
 <hugepages/>
</memoryBacking>

И запустить виртуальную машину с помощью virt-manager или команды

virsh start VIRTUAL_MACHINE_NAME

После того, как виртуальная машина будет запущена, убедитесь, что рассчетное количество Hugepages было аллоцировано процессом виртуальной машины - посмотрите на содержимое файла /proc/meminfo

grep Huge /proc/meminfo

Количество свободных страниц должно было уменьшиться на величину, равную объему оперативной памяти, отданной виртуальной машине деленной на размер Hugepage.

Если же вы вместо libvirt предпочитаете использовать qemu напрямую, просто добавьте в команду запуска виртуальной машину еще один ключик, приказывающий qemu использовать Hugepages:

qemu-.... –mem-path /dev/hugepages

Или

qemu-.... –mem-path /hugepages

в зависимости от того, куда вы решили монтировать hugetlbfs