KVM. Оптимизация работы с памятью при помощи Hugepages
Чтобы виртуальные машины, запущенные в 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