Найти в Дзене
Цифровая Переплавка

NUMA — новая «сеть» внутри сервера

Когда мы говорим о микросервисах и распределённых системах, чаще всего внимание сосредоточено на сетевых задержках: какие сервисы нужно расположить ближе друг к другу, какие узлы связать прямыми каналами, как уменьшить время отклика между датацентрами. Но сегодня появляется ещё один слой топологии, который зачастую остаётся за кадром — NUMA (Non-Uniform Memory Access). И он играет всё большую роль. NUMA — это архитектура памяти, при которой каждый процессорный сокет имеет собственные модули оперативной памяти. Доступ к «своей» памяти происходит быстро, а к «чужой» — через межсокетное соединение, что может увеличить задержку в 2–3 раза. На бумаге сотня наносекунд кажется мелочью, но в реальности это сотни тактов CPU и накопленный джиттер для сервисов с миллионами запросов в секунду. 💡 NUMA — это мини-сеть внутри одного сервера. И как в обычной сети, здесь тоже важна локальность: лучше «ходить к соседу в комнате», чем тянуться в соседнее здание. 🔑 Влияние на базы данных и кэши
Redis, C
Оглавление
Картинка иллюстрирует архитектуру NUMA с двумя сокетами: на каждом из них свой процессор и память, а сверху размещены микросервисы, взаимодействующие как с локальными, так и с удалёнными ресурсами.
Картинка иллюстрирует архитектуру NUMA с двумя сокетами: на каждом из них свой процессор и память, а сверху размещены микросервисы, взаимодействующие как с локальными, так и с удалёнными ресурсами.

Когда мы говорим о микросервисах и распределённых системах, чаще всего внимание сосредоточено на сетевых задержках: какие сервисы нужно расположить ближе друг к другу, какие узлы связать прямыми каналами, как уменьшить время отклика между датацентрами. Но сегодня появляется ещё один слой топологии, который зачастую остаётся за кадром — NUMA (Non-Uniform Memory Access). И он играет всё большую роль.

NUMA — это архитектура памяти, при которой каждый процессорный сокет имеет собственные модули оперативной памяти. Доступ к «своей» памяти происходит быстро, а к «чужой» — через межсокетное соединение, что может увеличить задержку в 2–3 раза. На бумаге сотня наносекунд кажется мелочью, но в реальности это сотни тактов CPU и накопленный джиттер для сервисов с миллионами запросов в секунду.

💡 NUMA — это мини-сеть внутри одного сервера. И как в обычной сети, здесь тоже важна локальность: лучше «ходить к соседу в комнате», чем тянуться в соседнее здание.

Практические эффекты NUMA

🔑 Влияние на базы данных и кэши
Redis, Cassandra, etcd — все эти системы зависят от скорости памяти. Если процессы и данные оказываются на разных NUMA-нодах, производительность падает, а задержки становятся нестабильными. В реальных тестах перенос Redis на «локальную» ноду устранял скачки задержек и делал throughput предсказуемым.

📈 Масштабирование через NUMA-выравнивание
В исследовании по Apache Cassandra учёные запускали отдельный инстанс на каждой NUMA-ноде. Результат — почти линейный рост производительности без покупки нового железа. По сути, каждая NUMA-нода стала «виртуальным сервером».

🛰 Телеком и real-time системы
В telco-нагрузках (например, CNF) важно обрабатывать пакеты за микросекунды. Если данные прыгают через NUMA-линк, это ломает SLA. Поэтому Kubernetes с Topology Manager и Memory Manager уже используется для строгого закрепления подов в одной NUMA-зоне.

Как Linux и Kubernetes помогают

🐧 Linux

  • Автоматическое NUMA-балансирование (AutoNUMA) анализирует доступ к страницам и перемещает их ближе к процессам.
  • numactl и cgroups позволяют вручную закреплять процессы и память за конкретными нодами.
  • eBPF открывает дорогу кастомным NUMA-чувствительным политикам прямо в ядре.

Kubernetes

  • CPU Manager закрепляет поды за конкретными ядрами.
  • Topology Manager решает, на какой NUMA-ноде лучше разместить CPU, память и устройства.
  • Memory Manager гарантирует, что память пода будет выделена локально.
  • Новые политики вроде single-numa-node позволяют запретить «растягивание» пода по нескольким зонам.

Мой взгляд

NUMA — это не просто «аппаратная особенность», это полноценный фактор в архитектуре. И чем выше плотность микросервисов на сервер, тем заметнее эффект. В моих экспериментах с PostgreSQL на двухсокетной машине перенос инстанса в «одну ноду» уменьшил 99-й перцентиль задержек почти вдвое — с 5 до 2,7 мс.

Мне кажется, правильный подход — воспринимать NUMA-зону как отдельный сервер. Если сервису нужны большие ресурсы, лучше поднять два пода на разных NUMA, чем один растянутый. Это как в распределённой архитектуре: горизонтальное масштабирование почти всегда лучше вертикального.

Чек-лист для инженеров ⚡

🖥️ Разворачиваете базу или кэш? — закрепите её в одной NUMA-ноде.
📊 Замеряете только средние задержки? — добавьте мониторинг tail latency. NUMA-«проколы» бьют именно туда.
🔧 Настраиваете Kubernetes? — включите Topology Manager и Memory Manager.
📡 Разрабатываете real-time сервис? — считайте NUMA частью сети, иначе SLA не сойдётся.

NUMA действительно стала «новой сетью» — только не между серверами, а внутри них. И те, кто это понимает, получают не просто проценты производительности, а более предсказуемые и стабильные системы.

🔗 Источники: