...

Балансирующий сервер NUMA: Оптимизация доступа к памяти для хостингового оборудования

Я показываю, как Сервер балансировки NUMA на хостинговом оборудовании оптимизирует доступ к памяти и снижает задержки за счет привязки процессов и данных к соответствующему узлу NUMA. Решающим фактором является Оптимизация доступа к памяти благодаря локальному доступу, размещению задач и целенаправленной миграции страниц на Linux-хостах с большим количеством ядер.

Центральные пункты

  • NUMA Разделяет процессоры и память на узлы; локальный доступ обеспечивает низкий Задержка.
  • Автоматический NUMA Balancing переносит страницы и размещает задачи рядом с узлом.
  • Размер виртуальной машины на узел, в противном случае существует риск NUMA Trashing.
  • Инструменты как показать numactl, lscpu, numad Топология и использовать.
  • ТюнингC-состояния, чередование узлов из, Огромные страницы, родственные связи.

Что такое NUMA - и почему это важно для хостинга

NUMA разделяет многопроцессорную систему на Узел, Каждый из них содержит собственные процессоры и локальную память, что делает доступ к близлежащим ядрам быстрее, чем к удаленным. В то время как UMA направляет все ядра по общему пути, NUMA предотвращает узкие места из-за местный каналов памяти на узел. В средах хостинга с большим количеством параллельных виртуальных машин каждая миллисекунда задержки суммируется, поэтому каждый запрос приносит ощутимую пользу. Если вам нужна дополнительная информация, вы можете узнать больше о архитектура NUMA. Для меня очевидно одно: если вы понимаете и используете узлы, вы получаете большую пропускную способность от того же оборудования.

Автоматическая балансировка NUMA в ядре Linux - как это работает

Ядро периодически сканирует части адресного пространства и „неотмеченные“ страницы, чтобы ошибка подсказки могла оптимальный узел видимым. Если сбой произошел, алгоритм оценивает, стоит ли перемещать страницу или перемещать задачу, и избегает ненужных перемещений. Миграция при сбое Данные ближе к исполняющему процессору, а размещение задач NUMA перемещает процессы ближе к их памяти. Сканер распределяет свою работу по частям так, чтобы накладные расходы оставались в пределах шума нормальной нагрузки. Это приводит к постоянной тонкой настройке, которая уменьшает задержки, не требуя жестких правил размещения.

Оптимизация доступа к памяти: локальная и удаленная

Для локального доступа используется Контроллер памяти собственного узла и минимизировать время ожидания интерконнекта. Удаленные доступы обходятся в несколько циклов через QPI/UPI или Infinity Fabric и, таким образом, минимизируют эффективное время доступа. Полоса пропускания. Высокое число ядер усугубляет этот эффект, поскольку все больше и больше ядер конкурируют за одни и те же соединения. Поэтому я планирую так, чтобы горячий код и активные данные собирались на одном узле. Если пренебречь этим, то можно потерять процентные пункты, определяющие время отклика или таймаут во время пиков нагрузки.

Размеры виртуальных машин, NUMA-мусор и обрезка хоста

Я определяю размеры виртуальных машин так, чтобы vCPU и оперативная память помещались в узле NUMA, чтобы избежать межузлового доступа. Часто 4-8 vCPU на узел обеспечивают хорошую производительность. Количество попаданий, в зависимости от платформы и иерархии кэша. Огромные страницы также помогают, поскольку TLB работает эффективнее и миграции страниц происходят реже. При необходимости я устанавливаю Сродство к процессору для процессов, критичных к задержкам, для привязки потоков к подходящим ядрам - подробнее см. Сродство к процессору. Если вы распределяете ВМ по узлам, вы рискуете получить NUMA trashing, т. е. пинг-понг данных и потоков.

Инструменты на практике: numactl, lscpu, numad

С помощью „lscpu“ я прочитал Топология и узлов NUMA, включая назначение ядер. Команда „numactl -hardware“ показывает память на узел и доступные расстояния, что облегчает оценку путей. Демон „numad“ следит за загрузкой и динамически корректирует сродство при перемещении центров нагрузки. Для фиксированных сценариев я использую „numactl -cpunodebind/-membind“ для явной привязки процессов и памяти. Таким образом, я сочетаю автоматическую балансировку с целевыми спецификациями и контролирую результат через „perf“, „numastat“ и „/proc“.

Как я измеряю влияние: Ключевые цифры и команды

Я всегда оцениваю NUMA-Tuning через Серия измерений, а не по интуиции. Три показателя доказали свою эффективность: Соотношение локальных и удаленных просмотров страниц, скорость миграции и распределение задержек (P95/P99).

  • В масштабах всей системыnumastat„ показывает локальные/удаленные доступы и перенесенные страницы для каждого узла.
  • Связанные с процессом: „/proc//numa_maps“ показывает, где находится память и как она была распределена.
  • Вид планировщикаCpus_allowed_list„ и реальный “Cpus_allowed„ проверяют, применяются ли привязки.
Общесистемное представление #
numastat
numastat -m

# Распределение и привязки, связанные с процессом
pid=$(pidof )
numastat -p "$pid"
cat /proc/"$pid"/numa_maps | head
cat /proc/"$pid"/status | grep -E 'Cpus_allowed_list|Mems_allowed_list'
taskset -cp "$pid"

# Счетчик ядра для активности NUMA
grep -E 'numa|migrate' /proc/vmstat

# Трассировка событий для глубокого анализа (активируется на короткое время)
echo 1 > /sys/kernel/debug/tracing/events/mm/enable
sleep 5; cat /sys/kernel/debug/tracing/trace | grep -i numa; echo 0 > /sys/kernel/debug/tracing/events/mm/enable

Я сравниваю в каждом случае A/B: несвязанные и связанные, автоматическое включение/выключение балансировки и различные срезы ВМ. Целью является явное снижение удаленных доступов и шума миграции, а также более жесткие задержки P95/P99. Только когда измеренные значения станут стабильно лучше, я возьмусь за настройку.

Настройки BIOS и встроенного ПО, которые действительно работают

Я отключаю „Node Interleaving“ в BIOS, чтобы структура NUMA оставалась видимой и ядро местный можно планировать. Сокращение C-состояний стабилизирует пики задержки, поскольку ядра реже впадают в состояние глубокого сна, что экономит время пробуждения. Я распределяю каналы памяти симметрично, чтобы каждый узел мог использовать свой максимальный объем памяти. Полоса пропускания достигнуто. Я тестирую префетчеры и функции RAS с помощью профилей рабочей нагрузки, поскольку они помогают или вредят в зависимости от схемы доступа. Я измеряю каждое изменение по сравнению с базовым уровнем и только после этого принимаю настройку на постоянной основе.

Параметры ядра и sysctl, которые делают разницу

Тонкая настройка ядра помогает мне, Накладные и Время отклика балансировщика в соответствии с рабочей нагрузкой. Я начинаю с консервативных настроек по умолчанию и продвигаюсь вперед шаг за шагом.

  • kernel.numa_balancingВключение/выключение автоматической балансировки. Я оставляю его включенным для движущихся грузов; я выключаю его для строго прижатых специальных услуг в качестве теста.
  • kernel.numa_balancing_scan_delay_msВремя ожидания перед первым сканированием после создания процесса. Выберите большее время, если выполняется много кратковременных задач; меньшее - для долго работающих служб, требующих быстрого приближения.
  • kernel.numa_balancing_scan_period_min_ms / _max_msШирина интервалов сканирования. Узкие интервалы увеличивают скорость отклика, но также и нагрузку на процессор.
  • kernel.numa_balancing_scan_size_mbДоля адресного пространства за одно сканирование. Слишком большая доля порождает штормы с подсказками, слишком маленькая - реагирует вяло.
  • vm.zone_reclaim_mode: Если памяти не хватает, ядро предпочитает локальное восстановление вместо удаленного выделения. Для общих рабочих нагрузок на хостинге я обычно оставляю 0; Для сервисов с локальной памятью, чувствительных к задержкам, я осторожно тестирую более высокие значения.
  • Прозрачные огромные страницы (THP): В разделе „/sys/kernel/mm/transparent_hugepage/{enabled,defrag}“ я обычно устанавливаю значение madvise и консервативной дефрагментации. Жесткие профили „всегда“ дают преимущества TLB, но рискуют застопориться из-за уплотнения.
  • sched_migration_cost_ns: Оценка стоимости миграции задач. Более высокие значения снижают эффективность перераспределения агрессивных планировщиков.
  • cgroups cpusetС cpuset.cpus и cpuset.mems Я чисто разделяю службы по узлам и убеждаюсь, что первое касание остается в пределах допустимых узлов.
# Пример: консервативная, но отзывчивая балансировка
sysctl -w kernel.numa_balancing=1
sysctl -w kernel.numa_balancing_scan_delay_ms=30000
sysctl -w kernel.numa_balancing_scan_period_min_ms=60000
sysctl -w kernel.numa_balancing_scan_period_max_ms=300000
sysctl -w kernel.numa_balancing_scan_size_mb=256

# Осторожно используйте THP
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
echo defer > /sys/kernel/mm/transparent_hugepage/defrag

Это по-прежнему важно: Меняйте только один регулировочный винт в каждом тестовом раунде и проверяйте эффект на одной и той же кривой нагрузки. Именно так я отделяю причину от следствия.

Правильно размещайте рабочие нагрузки: Базы данных, кэши, контейнеры

Базы данных выигрывают, когда буферные пулы остаются локальными для каждого узла NUMA, а потоки привязаны близко к своим кучам. В кэшах in-memory я устанавливаю значение sharding на Узел чтобы избежать удаленного поиска. Контейнерные платформы получают ограничения и запросы, чтобы поды не прыгали по узлам. Для резервирования памяти я использую Huge Pages, что упрощает хранение хотсетов в Кэши подходят. В следующей таблице компактно представлены стратегии и типичные эффекты.

Стратегия Используйте Ожидаемый эффект Подсказка
первое касание Базы данных, кучи JVM Выделение местной стороны Выполните инициализацию на целевом узле
Interleave Широко распределенная нагрузка Равномерное распределение Не оптимально для горячих точек
Прикрепление задач Услуги, критичные к задержкам Постоянная задержка Менее гибкие при изменении нагрузки
Автоматическая балансировка Смешанные рабочие нагрузки Динамическая близость Соизмерение накладных расходов с прибылью
Огромные страницы Большие кучи, кэши Меньше пропусков TLB Планируйте чистые резервации

Виртуализация: виртуальная NUMA, планировщик и настройка гостей

Virtual NUMA передает топологию хоста гостевой ОС в упрощенном виде, так что первое касание и Аллокатор работать разумно. Планировщики гипервизора обращают внимание на близость узлов при распределении vCPU и миграции ВМ. Я редко распределяю большие ВМ по нескольким узлам, если только рабочая нагрузка не распределяется широко и не выигрывает от чередования. В гостевой системе я настраиваю кучи JVM или баз данных таким образом, чтобы они оставались локальными на видимых узлах NUMA. Что касается управления памятью в гостевой среде, посмотрите на Виртуальная память, чтобы уменьшить размер страниц и их переключение.

Близость PCIe: NVMe и сетевые карты на нужных узлах

Если возможно, я назначаю SSD-накопители NVMe и быстрые сетевые карты узлу, на котором работает Рабочая нагрузка выполняется. Таким образом, я избегаю запросов ввода-вывода, пересекающих межсоединение и увеличивающих задержку. Я привязываю многоочередные сетевые карты к наборам ядер узла с помощью RSS/RPS, чтобы IRQ оставались локальными. Для стеков хранения стоит разделить пулы потоков по узлам. Если вы уделите этому внимание, то заметно снизите задержки P99 и создадите резерв для пиков нагрузки.

IRQ и сродство очередей на практике

Сначала я проверяю, какие Узел NUMA устройств и соответствующим образом подключать IRQ и очереди. Это обеспечивает локальность путей передачи данных.

Сопоставление устройств # с узлами
cat /sys/class/net/eth0/device/numa_node
cat /sys/block/nvme0n1/device/numa_node

# Установите специальное сродство IRQ (пример: ядра 0-7 узла)
irq=
echo 0-7 > /proc/irq/$irq/smp_affinity_list

# Привязка очередей сетевых карт к ядрам (RPS/RFS)
for q in /sys/class/net/eth0/queues/rx-*; do echo 0-7 > "$q"/rps_cpus; done
sysctl -w net.core.rps_sock_flow_entries=32768
for q in /sys/class/net/eth0/queues/rx-*; do echo 4096 > "$q"/rps_flow_cnt; done

# Улучшение сродства очереди NVMe
echo 2 > /sys/block/nvme0n1/queue/rq_affinity
cat /sys/block/nvme0n1/queue/scheduler # "none" предпочтительнее

„Я запускаю “irqbalance" с осознанием узла или устанавливаю его на исключения для прерываний "горячего пути". Результат - более стабильные задержки, меньшее количество переходов между узлами через IRQ и ощутимое увеличение количества локальных обращений ввода-вывода.

Статическая привязка против динамической балансировки - средний путь

Я использую „наборы задач“ и cgroups, чтобы установить жесткие правила, когда детерминированные Латентность Считает. Я оставляю автоматическую балансировку NUMA активной, когда нагрузка смещается и мне нужно адаптивное приближение. Часто лучше всего работает сочетание: жесткие контакты для горячих трасс, более открытые границы для вспомогательной работы. Я регулярно проверяю, не увеличивается ли количество миграций, так как это сигнализирует о плохом планировании. Цель по-прежнему состоит в том, чтобы выбрать расположение данных и потоков таким образом, чтобы миграции были редкими, но возможными.

NUMA в контейнерах и Kubernetes

Я беру с собой контейнер cpusets и Огромные страницы на линии. Я назначаю капсулы/контейнеры на узел NUMA, сохраняя согласованные объемы процессора и памяти. В оркестрах я устанавливаю политики, которые предпочитают назначение на один узел и, таким образом, соблюдают принцип "первого касания".

  • Время выполнения контейнера: „-cpuset-cpus“ и „-cpuset-mems“ удерживают задачи и память вместе; назначают огромные страницы в качестве ресурсов.
  • Менеджер топологии/процессораСтрогое или предпочтительное назначение обеспечивает выделение соответствующих ядер и областей памяти.
  • Гарантированный QoSФиксированные запросы/лимиты минимизируют перераспределение планировщиком.

Я сознательно разделил побочные и вспомогательные процессы на другие ядра. в пределах того же узла, чтобы горячий путь оставался неповрежденным, но не вступал в межузловую гонку.

Понимание топологий процессоров: CCD/CCX, SNC и Cluster-on-Die

Современные серверные процессоры разделяют сокеты на Поддомены со своими собственными кэшами и путями. Я учитываю это при сокращении ядер и куч:

  • AMD EPYCCCD/CCX и „NUMA на сокет“ (NPS=1/2/4) влияют на то, насколько тонко будет выстроена NUMA. Большее количество узлов (NPS=4) повышает локальность, но требует чистого пиннинга.
  • IntelSub-NUMA Clustering (SNC2/4) разделяет LLC на кластеры. Хорошо подходит для нагрузок с ограниченным объемом памяти, при условии, что ОС и рабочая нагрузка ориентированы на узлы.
  • Близость L3Я связываю потоки, использующие одни и те же кучи, в один кластер L3, чтобы сэкономить трафик когерентности и межкластерные переходы.

Эти опции действуют как мультипликатор: при правильном использовании они увеличивают Местность Кроме того, при неправильной настройке они увеличивают фрагментацию и удаленный трафик.

Пошаговое внедрение и план отката

Я никогда не представляю „большой взрыв“ NUMA-тюнинга. Устойчивый План позволяет избежать неожиданностей:

  1. Базовый уровеньАппаратная топология, задержки P50/P95/P99, пропускная способность, захват скорости numastat.
  2. ГипотезаСформулируйте конкретную цель (например, удаленный доступ -30%, P99 -20%).
  3. Один шагИзмените только один регулировочный винт (например, VM cut, cpuset, политика THP, интервалы сканирования).
  4. КанарыПротестируйте 5-10% парка под реальной нагрузкой, сохраните готовность к откату.
  5. ОценкаСравнивайте измеренные значения, определяйте окна регрессии, регистрируйте побочные эффекты.
  6. РазвернутьРаскатывайте вал за валом, измеряйте еще раз после каждого вала.
  7. Техническое обслуживаниеПроводите повторные измерения раз в квартал (обновления ядра, прошивки и рабочей нагрузки меняют оптимальный показатель).

Это гарантирует воспроизводимость улучшений и возможность их отмены в течение нескольких минут в случае ошибки.

Распространенные ошибки - и как их избежать

Типичной ошибкой является активация в BIOS функции чередования узлов, которая скрывает топологию NUMA и Балансировка сложнее. Столь же неблагоприятны ВМ с большим количеством vCPU, чем предлагает узел, плюс неаккуратно зарезервированные огромные страницы. Некоторые администраторы жестко привязывают все к узлам и тем самым теряют гибкость при изменении рабочей нагрузки. Другие полностью полагаются на ядро, хотя жесткие "горячие точки" требуют четких правил. Я записываю серии измерений, выявляю отклонения на ранних этапах и шаг за шагом корректирую настройки и политики.

  • THP „Всегда“ без контроля: незапланированное уплотнение нарушает латентность. Я предпочитаю использовать „madvise“ и специально резервировать огромные страницы.
  • vm.zone_reclaim_mode слишком агрессивно: локальное восстановление может принести больше вреда, чем пользы, в самый неподходящий момент. Сначала отмерьте, потом оттачивайте.
  • слепой иркбалансНекритические IRQ перемещаются между узлами. Я устанавливаю исключения или фиксированные маски для горячих путей.
  • Смесь чередования + жесткого прижимаПротиворечивая политика порождает пинг-понг. Я принимаю решение в пользу четкой линии для каждой услуги.
  • Нечистые кпусетыКонтейнеры видят узел, но отображают память на другие узлы. Всегда устанавливайте „cpuset.mems“ последовательно с набором CPU.
  • Особенности суб-НУМА активированы, но не используются: Увеличение количества узлов без планирования увеличивает фрагментацию. Включайте только после тестирования.

Краткое резюме

NUMA Balancing Server целенаправленно объединяет процессы и данные, делая локальный доступ более частым и эффективным. Задержки становятся короче. При подходящем размере виртуальной машины, чистой конфигурации BIOS и использовании таких инструментов, как numactl, создается четкая топология, которую использует ядро. Виртуальная NUMA, огромные страницы и аффинити дополняют автоматическую балансировку, а не заменяют ее. Подключение устройств ввода-вывода рядом с узлами и использование "горячих путей" позволяет отказаться от дорогостоящего удаленного доступа. Таким образом, оборудование хостинга надежно масштабируется, а каждая процессорная секунда приносит больше пользы. полезная нагрузка.

Текущие статьи

Балансирующий сервер NUMA с оптимизированным доступом к памяти хостингового оборудования
Серверы и виртуальные машины

Балансирующий сервер NUMA: Оптимизация доступа к памяти для хостингового оборудования

Сервер балансировки **NUMA** революционизирует оптимизацию доступа к памяти на **хостинговом оборудовании**. Сократите задержки и увеличьте производительность сервера.

Фотореалистичная графика для потоковой передачи HTTP-ответов в хостинговых средах
Веб-сервер Plesk

Потоковая передача HTTP-ответов в хостинге: оптимизация веб-производительности

Потоковая передача HTTP-ответов в хостинге оптимизирует **производительность веб-сайтов** благодаря кодированию передачи данных в виде кусков и потоковой передаче http-ответов для ускорения загрузки.

Гиперпоточность процессора в хостинговых серверах с логическими ядрами
Серверы и виртуальные машины

Гиперпоточность процессора в хостинге: преимущества и риски

Гиперпоточность процессора в хостинге повышает производительность логических ядер, но таит в себе риски. Узнайте о настройке сервера для достижения оптимальной производительности веб-сервера.