К основному содержимому

NUMA на двух процессорах: привязка процессов и память

Выделенные серверы · 29.09.2026

Что такое NUMA и почему это важно на двух процессорах

NUMA (Non-Uniform Memory Access) — архитектура памяти двухпроцессорного сервера, где у каждого CPU есть "своя" память с быстрым доступом и "чужая" память другого сокета с доступом через межпроцессорную шину. Тема актуальна в первую очередь для серверов с двумя и более сокетами — то, как выбран процессор, напрямую определяет число узлов NUMA и их размер.

Если приложение не учитывает NUMA, планировщик ОС может разместить процесс на одном сокете, а память выделить на другом. Результат — просадка производительности без видимой причины в мониторинге CPU.

Как посмотреть топологию NUMA

lscpu | grep -i numa
numactl --hardware

Команда numactl --hardware покажет количество узлов, объём памяти на каждом и расстояния между узлами (node distances). Значение 10 — обращение к своему узлу, 20-21 — к соседнему: чем выше число, тем дороже промах.

Проблема: память "не своего" узла

Типичный сценарий: сервер на двух процессорах, 256 ГБ памяти, приложение запущено без привязки. Планировщик Linux переносит процесс между ядрами разных сокетов, а выделенная память остаётся на первом узле. Каждое обращение ко второму сокету идёт через межпроцессорный интерконнект, и задержка растёт.

Это особенно заметно на серверах баз данных, где кэш и буферы должны жить рядом с ядрами, которые их читают тысячи раз в секунду.

Привязка процессов: numactl и cpuset

Явная привязка процесса к узлу решает проблему напрямую:

numactl --cpunodebind=0 --membind=0 /usr/bin/mysqld
numactl --interleave=all /usr/bin/myapp

Флаг --cpunodebind закрепляет процесс за ядрами узла 0, --membind — за памятью того же узла. Флаг --interleave=all распределяет память равномерно по всем узлам — полезно для приложений, которые сами не умеют работать с NUMA и не выигрывают от локальности.

ПараметрЧто делаетКогда использовать
--cpunodebindЗакрепляет ядра узлаСУБД, JVM с большой кучей
--membindЗакрепляет память узлаВместе с cpunodebind
--interleave=allЧередует память по узламNUMA-неосведомлённые приложения
--preferredПредпочитает узел, но не запрещает другиеГибкая нагрузка

NUMA в базах данных и виртуализации

PostgreSQL и MySQL рекомендуют запускать один инстанс на NUMA-узел при больших объёмах памяти либо явно привязывать процесс через numactl, если инстанс один на весь сервер. В виртуализации (KVM, Proxmox) стоит выделять виртуальной машине vCPU и память в пределах одного физического узла — иначе гипервизор столкнётся с той же проблемой межузлового трафика.

Перед изменением привязки измерьте эффект: прогоните тест до и после через sysbench с нагрузкой, близкой к реальной, а не синтетической однопоточной.

Чек-лист настройки NUMA

  • Проверьте topology через numactl --hardware до тюнинга, не после.
  • Привязывайте процесс к CPU и памяти вместе, а не по отдельности.
  • Для NUMA-неосведомлённых приложений используйте --interleave=all вместо ручной привязки.
  • Замеряйте задержки и throughput до и после — прирост не всегда очевиден на слабой нагрузке.
← Назад в базу знаний Задать вопрос поддержке