====== Proxmox: HugePages для виртуальных машин ====== Когда приложению нужно получить значение какой-то переменной, оно просит процессор достать его из памяти по адресу этой переменной. Но этот адрес виртуальный, и процессору приходится переводить его в физический - то есть в реальное место на чипе памяти сервера. Память у процессора разбита на блоки, которые называются страницами, и размер страницы зависит от архитектуры CPU. Например, в системах x86_64 каждая страница обычно равна 4 КБ. Получается, что на сервере с 16 ГБ памяти будет примерно 4 миллиона страниц. И вот здесь может начаться проблема: чем больше памяти у сервера, тем больше страниц приходится обслуживать процессору. А перевод виртуальных адресов в физические начинает замедляться. Чтобы ускорить работу, придумали HugePages. HugePage - это страница, которая больше стандартной. В x86_64 их размер может быть либо 2 МБ, либо 1 ГБ. За счёт этого у процессора становится меньше страниц для управления, и всё работает быстрее. Например, если вы создаёте виртуальную машину (VM) с 1 ГБ памяти, Linux по умолчанию разобьёт её на примерно 256 000 страниц. А если использовать HugePages размером 1 ГБ - будет всего одна страница. Количество работы для процессора резко уменьшается, и производительность растёт. **Как настроить HugePages** Сначала проверьте, какие размеры HugePages поддерживает ваша система. Для этого выполните команду: ls /sys/devices/system/node/node0/hugepages/ Пример вывода для AMD EPYC: hugepages-1048576kB hugepages-2048kB Пример вывода для ARM Ampere Altra: hugepages-1048576kB hugepages-2048kB hugepages-32768kB hugepages-64kB Это значит, что на AMD доступны HugePages размером 4KB, 2MB и 1GB. В примере мы будем использовать HugePages по 1GB. Чтобы их настроить, нужно отредактировать файл ''/etc/default/grub'' и добавить параметры ''default_hugepagesz'' и ''hugepagesz'' в переменную ''GRUB_CMDLINE_LINUX''. В нашем случае выставим размер страницы 1GB и количество HugePages равным 16: GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=16" Если у вас архитектура NUMA, то параметры ''hugepagesz'' и ''hugepages'' придётся задавать для каждого узла отдельно. Например, если у вас 2 узла, количество HugePages нужно разделить и указать в формате ''$HUNODE:$AMOUNT,$HUNODE:$AMOUNT'': GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=0:8,1:8" Ядро Linux резервирует под HugePages 16 ГБ памяти, но эта память используется //только// для HugePages и недоступна остальным приложениям. Поэтому количество HugePages нужно рассчитывать исходя из общей памяти сервера, оставив запас для самой системы и других приложений. Для операционной системы должно оставаться минимум 1 ГБ свободной памяти. Если вы используете ZFS или Ceph — им тоже нужно выделить дополнительную память. После того как вы отредактировали ''/etc/default/grub'', обновите конфигурацию grub: update-grub И не забудьте перезагрузить сервер, чтобы изменения вступили в силу. Проверить HugePages можно командой: cat /proc/meminfo | grep Huge Пример вывода: AnonHugePages: 0 kB ShmemHugePages: 0 kB FileHugePages: 0 kB HugePages_Total: 448 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 1048576 kB Hugetlb: 469762048 kB Если у вас NUMA-архитектура, HugePages нужно проверять для каждого узла. Для этого выполните: numastat -cm | egrep "Huge|Node|Mem" Пример вывода: Node 0 Node 1 Node 2 Node 3 Total MemTotal 128655 129020 129020 128977 515672 MemFree 12654 12933 12643 13139 51369 MemUsed 116001 116087 116377 115838 464303 AnonHugePages 0 0 0 0 0 ShmemHugePages 0 0 0 0 0 HugePages_Total 114688 114688 114688 114688 458752 HugePages_Free 0 0 0 0 0 HugePages_Surp 0 0 0 0 0 В этом примере у нас 4 узла, на каждом по 128 ГБ памяти, и на каждом выделено по 112 HugePages (112 × 1024 = 114 688 MB). **Как настроить HugePages для виртуальных машин** Большинство параметров HugePages недоступны из интерфейса Proxmox. Их нужно задавать через командную строку или API. В примере будем использовать HugePages размером 1 ГБ. Количество HugePages зависит от объёма памяти, выделенной ВМ. Для ВМ с 8192 MB памяти это будет 8 HugePages. Пример конфигурации ВМ ''/etc/pve/qemu-server/$ID.conf'': # VM config /etc/pve/qemu-server/$ID.conf memory: 8192 hugepages: 1024 keephugepages: 1 HugePages - это выделенные страницы памяти, закреплённые за конкретной ВМ. Другие виртуалки не могут использовать те же страницы. Параметр ''keephugepages'' позволяет оставлять HugePages зарезервированными даже после остановки ВМ. Такая схема не только ускоряет работу, но и повышает безопасность ВМ. Некоторые приложения, например базы данных, умеют использовать HugePages для хранения данных в памяти. Это ускоряет доступ к данным. Чтобы разрешить использование HugePages внутри ВМ, добавьте флаг CPU ''+pdpe1gb'' в конфигурацию: # VM config /etc/pve/qemu-server/$ID.conf cpu: host,flags=+pdpe1gb;