До основного вмісту

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 до і після — приріст не завжди очевидний на слабкому навантаженні.
← Назад до бази знань Поставити питання підтримці