...

Балансировка NUMA в Linux: отключить или оставить включенной?

Балансировка NUMA в Linux определяет, будет ли Ядро доступ к памяти локализуется автоматически или же я самостоятельно управляю размещением. В этом руководстве я покажу, когда следует оставлять numa balancing включенным, а когда — отключить его для Латентность-Отключить защиту.

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

  • Автоматический помогает при смешанных рабочих нагрузках без настройки NUMA.
  • Отключить при пиннинге, статических политиках или высокой задержке.
  • Накладные возникает в результате сканирования, сбоев и миграций.
  • Конфигурация управлять с помощью sysctl или параметров загрузки.
  • Тестирование и измерить, а не гадать, а потом принять решение.

Краткое объяснение NUMA: задержки и локальность

В системах NUMA аппаратное обеспечение распределяет память по нескольким узлам, каждый из которых Процессоры находятся близко друг к другу. Локальные обращения занимают меньше времени, чем удаленные, что я сразу заметил по Латентность и пропускную способность. Если процесс работает на одном узле, а данные хранятся на другом, я теряю ценные микросекунды при каждом обращении. Именно в этом месте вступает в действие ядро и оптимизирует Местоположение со стороны. Тот, кто понимает основную идею, быстро осознает: близость вычислительных ядер к данным — это прямой путь к постоянной Производительность.

Как работает автоматическая балансировка NUMA

Ядро отслеживает, с каких ядер процесс обращается к страницам, и целенаправленно запускает Подсказка-Faults. Таким образом он определяет, какой узел получает доминирующие запросы, и затем перемещает соответствующие страницы туда. Эти миграции сокращают удаленные запросы и повышают локальную Скорость попадания. Я особенно замечаю этот эффект при динамических рабочих нагрузках, когда потоки перемещаются, а память меняет своё расположение. Те, кто хочет углубиться в эту тему, могут изучить взаимосвязь между близостью процессора и памяти через Аффинность процессора и памяти понять на практике.

Когда следует оставить в активном режиме: типичные рабочие нагрузки

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

Когда отключать: четкие критерии

Я отключаю автопилот, как только осознаю, что заплываю или выхожу из курса Политика устанавливаю. Если я использую numactl, cgroups или MPOL_BIND/MPOL_PREFERRED, то выбор путей доступа к памяти уже определён. В этом случае ошибки Hint-Faults и миграции приводят к ненужному Накладные. То же самое касается сценариев работы в режиме реального времени или высокочастотной торговли (HFT), где важна каждая микросекунда и приоритетом является предсказуемость. Тем, кто более глубоко изучает вопрос выбора правил размещения, будет полезно ознакомиться с подходящими Политики использования памяти.

Понимание и измерение накладных расходов

Автоматическая балансировка влечёт за собой дополнительную работу: сканирование, Неисправности а перемещение страниц отнимает время процессора. Это почти незаметно, когда количество удалённых запросов значительно снижается, но едва ли оправдывает себя, если макет уже находится локально. Поэтому я всегда проверяю фактический эффект с помощью numastat, perf и информативных Бенчмарки. Интересно наблюдать динамику в течение нескольких минут, а не только кратковременный пик. Только когда показатели стабильно свидетельствуют о росте локальных обращений и снижении задержек, я оставляю этот режим включенным.

Настройка: Sysctl и параметры загрузки

Я проверяю статус через /proc или Sysctl и при необходимости сразу же изменяю его, не запуская Перезапустите. Для тестирования достаточно простых команд, таких как приведенные ниже, которые я выполняю в консоли. На постоянной основе я задаю это значение в файле sysctl, чтобы оно сохранялось после перезагрузки. Те, кто хочет настроить это ещё на этапе загрузки, могут использовать параметр ядра numa_balancing=enable или отключить. Я фиксирую каждое изменение и отмечаю, на каком этапе рабочей нагрузки я его внес.

cat /proc/sys/kernel/numa_balancing
echo 0 > /proc/sys/kernel/numa_balancing
sysctl -w kernel.numa_balancing=1
# /etc/sysctl.d/90-numa.conf
# kernel.numa_balancing = 0

Сценарии использования контейнеров и виртуализации

На хостах с большим количеством виртуальных машин и контейнеров автоматическая Локализация часто проявляют свои преимущества. Процессы запускаются и завершаются, Cgroups перераспределяют нагрузку, а ядро удерживает память ближе к активным ядрам. Я наблюдаю это прежде всего на крупных серверах с несколькими сокетами и несколькими узлы. Особые случаи со строгой привязкой отдельных экземпляров я четко выделяю и целенаправленно отключаю в них автоматический режим. Для более подробной классификации полезно ознакомиться с практическими Оптимизация NUMA в режиме хоста.

Таблица решений для практического применения

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

Сценарий Типичное действие Моя рекомендация
Стандартные рабочие нагрузки без настройки NUMA Больше локальных обращений, меньше удаленных Читает Оставить активным
Базы данных с изменяющейся нагрузкой Динамическая локализация страниц, умеренная Сканирование Оставить в активном состоянии, протестировать
Твердое время реального действия или HFT Задержка при ошибке Hint мешает Джиттер-Цели Отключить, закрепить вручную
Ручная фиксация ресурсов с помощью numactl/cgroups Автоматика вступает в противоречие с фиксированными Политика Отключить
Статические политики управления памятью (MPOL_BIND и т. д.) Миграции не приносят реальной Преимущество Отключить
Тестовая/аналитическая среда Хороший обзор местности и Эффекты Оставить в активном состоянии, проверить варианты

Руководство по тестированию и валидации

Я запускаю систему с включенным балансировщиком и фиксирую результаты сравнения локальных и удаленных Доступы с помощью numastat. После этого я отключаю эту функцию и повторяю измерения точно так же. Различия я оцениваю не только по средним значениям, но и по Проценты. Регрессионные тесты с использованием профилей нагрузки, полученных в производственной среде, дают наиболее достоверные результаты. Только после этого я принимаю окончательное решение в пользу хоста, виртуальной машины или конкретного Сервис.

Распространенные трудности и мифы

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

Пределы автоматизации и взаимодействия

AutoNUMA оказывает сильное влияние на анонимные страницы, которые процесс выделяет самостоятельно. Однако не всё можно разумно перенести. Закрепленные страницы (mlock), память DMA/устройств, DAX или области, зарегистрированные RDMA, остаются на своих местах. Даже совместно используемые страницы (например, интенсивно используемые библиотеки или кэш страниц) приносят лишь ограниченную пользу от миграции, поскольку несколько процессов конкурируют за Схема доступа производить. Кроме того, я учитываю затраты на Прозрачные огромные страницы (THP): их перемещение обходится дороже, чем в случае со страницами размером 4 КиБ, и может вызывать пиковые нагрузки. Те, кто стремится к строгим целевым показателям задержки, часто сочетают настройку THP=never или madvise с отключенной балансировкой и чистым пиннингом, чтобы исключить неожиданности.

Еще одним аспектом является взаимодействие с планировщиком ЦП. Планировщик стремится размещать потоки там, где находятся их данные, а балансировщик перемещает данные туда, где выполняются потоки. Эти два механизма дополняют друг друга, но при нестабильной нагрузке могут на короткое время привести к Колебания приводят. На практике интервалы сканирования смягчают эти эффекты; если наблюдаются крайне нестабильные профили нагрузки, ситуацию можно стабилизировать за счет более длительных периодов сканирования или более стабильной фиксации потоков.

Точная настройка параметров сканирования

Помимо общего переключателя, существуют параметры ядра, с помощью которых я могу точно настроить степень активности автоматической системы. Их точные названия могут немного различаться в зависимости от версии ядра, но их назначение остаётся неизменным:

  • kernel.numa_balancing_scan_delay_ms: время ожидания после запуска, вызова fork или exec до начала первого сканирования.
  • kernel.numa_balancing_scan_period_min_ms / _max_ms: нижний и верхний пределы периодичности сканирования для каждого диапазона адресов процесса.
  • kernel.numa_balancing_rate_limit_mb: верхний предел количества миграций страниц за временной интервал для экономии пропускной способности памяти.
  • kernel.numa_balancing_scan_size_mb: объем памяти, который помечается за один проход сканирования (если доступно).

В конфигурациях, где задержка имеет критическое значение, я, следуя консервативному подходу, увеличиваю минимальный и максимальный периоды и снижаю ограничения скорости, вместо того чтобы сразу отключать автоматику. Это часто позволяет найти оптимальный компромисс: меньше ошибок «hint-fault», меньше миграций, но при этом сохраняется достаточная реакция на реальные случаи неправильного размещения.

Примеры # (временные, до перезагрузки)
sysctl -w kernel.numa_balancing_scan_period_min_ms=60000
sysctl -w kernel.numa_balancing_scan_period_max_ms=240000
sysctl -w kernel.numa_balancing_rate_limit_mb=64

Подробный анализ показателей и диагностика

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

  • numastat: соотношение локальных и удаленных обращений в масштабе всей системы и по каждому процессу.
  • /proc//numa_maps: распределение страниц памяти процесса по узлам, включая флаги, такие как active, file, anon.
  • /proc/vmstat: такие счетчики, как numa_hint_faults, numa_hint_faults_local и numa_pages_migrated, показывают, работает ли балансировщик и Успех есть.
Обзор # по каждому процессу
numastat -p 

Подробный просмотр #: где расположены какие области?
grep -E 'anon|file' /proc//numa_maps | head

#: обзор активности AutoNUMA на уровне ядра
grep -E 'numa_(hint_faults|pages_migrated)' /proc/vmstat

В результатах я ищу тенденции: стабильно ли растёт доля локальных обращений? Сокращается ли при этом количество ошибок «Hint-Faults»? Если да, значит, макет работает хорошо. Если доля локальных запросов остаётся на прежнем уровне, несмотря на многочисленные миграции, я скорее потрачу лишние циклы. Для оценки целевых значений задержки я дополнительно проверяю 95-й и 99-й процентили времени отклика; небольшое улучшение среднего значения может быть перекрыто Джиттер будут закрыты.

Профили рабочей нагрузки: что обычно работает

На основе практического опыта выявились закономерности, когда AutoNUMA, как правило, помогает, а когда — нет:

  • Службы JVM и серверы приложений: зачастую они работают эффективно, если не используется жесткая стратегия привязки потоков и не задействована агрессивная собственная логика NUMA. Некоторые среды выполнения предлагают настройки NUMA; если я строго их использую, то ограничиваю работу автоматики или отключаю её.
  • Реляционные базы данных: при переменной нагрузке со смешанными кэшами автоматическая настройка часто работает хорошо. Однако если я включаю выделенное привязывание (Worker-to-Node, строго распределенные общие буферы), я отключаю балансировку для обеспечения точной воспроизводимости.
  • Хранилища в памяти и кэши: большой, активно используемый набор данных выигрывает от локального размещения. Если экземпляр работает в однопоточном режиме или строго закреплён, я предотвращаю ненужные миграции, отключив эту функцию.
  • HPC/MPI и научные коды: в большинстве случаев существуют четкие правила размещения и привязки (OpenMP/numactl). Здесь предсказуемость важнее автоматизации — я отключаю NUMA-балансировку.

Виртуализация: vNUMA, привязка и миграция в режиме реального времени

Рассматривая взаимодействие между хозяином и гостем, я учитываю оба уровня:

  • Если топология vNUMA в гостевой системе совпадает с физической топологией NUMA хоста, балансировщик гостевой системы может принимать обоснованные решения. В случае отклонения от этого возникают „ложные соседства“, которые AutoNUMA компенсирует лишь в ограниченной степени.
  • Если я жестко привязываю виртуальные процессоры (vCPU) к процессорам хоста и привязываю память гостевой системы к определенным узлам, это является явной политикой — я уменьшаю или отключаю AutoNUMA на уровне этой виртуальной машины, чтобы избежать двойных миграций.
  • После миграций в режиме реального времени я наблюдаю фазу «разогрева»: количество ошибок Hint-Faults растет до тех пор, пока не установится новое равновесие. В этот период я планирую буферы для Латентность-кончики.

На высоконагруженных хостах виртуализации, где запуск и остановка экземпляров, а также cgroups перераспределяют нагрузку, автоматическая настройка на уровне хоста зачастую остаётся чистым преимуществом. Для выделенных виртуальных машин, чувствительных к „шумным соседям“, я тщательно изолирую ресурсы и устанавливаю правила в статическом режиме.

Прагматичные целевые значения и критерии приемлемости

Сначала я определю, что значит „хорошо“, чтобы не тратить время на бесконечную доработку:

  • Общие службы: 70–85% локальных обращений часто бывает достаточно, если дисперсия остается небольшой.
  • SLA по задержке: целевой показатель >90% локально, четкие верхние пределы для показателя частоты скрытых сбоев и стабильные 99-й процентили.
  • С высокой нагрузкой на пропускную способность: миграции не должны перегружать каналы хранения — соответствующим образом скорректируйте ограничения скорости и периоды.

Я фиксирую эти пороговые значения и анализирую результаты A/B-тестов в течение нескольких фаз нагрузки. Решение я принимаю только тогда, когда результаты становятся воспроизводимыми.

Контрольный список по устранению неполадок

  • Внезапные всплески латентности: проверьте, существует ли корреляция между миграциями THP и пиками в показателе `numa_hint_faults`. Меры по устранению: увеличьте периоды сканирования, установите для THP значение `madvise/never`, в крайнем случае — отключите балансировку.
  • Практически нет эффекта, несмотря на активацию: возможно, потоки жестко закреплены или существуют фиксированные политики использования памяти? В таком случае автоматическая система вступает в конфликт с заданными настройками.
  • Высокая скорость миграции, но при этом много удаленных обращений: проверьте и увеличьте ограничение скорости; в качестве альтернативы стабилизируйте рабочую нагрузку (фиксация потоков, поддержание кэшей в «теплом» состоянии).
  • Неясные результаты измерений: используйте представление по процессам с помощью команды numastat -p и каталога /proc//numa_maps, а не только общие системные показатели.

Часто упускаемые из виду детали

  • Рабочие нагрузки, в значительной степени зависящие от кэша страниц: AutoNUMA действует в первую очередь на анонимные страницы. Тем, чья работа в основном зависит от операций ввода-вывода, не стоит ожидать чудес от балансировки.
  • Cgroups и cpusets: файл cpuset.mems ограничивает круг узлов, к которым группа имеет доступ. Это жесткие рамки, в пределах которых работает автоматический механизм.
  • «Memory-Hotplug»/перевод узла в автономный режим: динамические топологии изменяют расстояния; после внесения изменений рекомендуется провести повторное тестирование и, при необходимости, скорректировать параметры сканирования.

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

Для обычных серверных нагрузок я оставляю автоматический режим включенным, так как без ручного вмешательства он обеспечивает почти Данные приводит к задействованию ядер. При работе в режиме реального времени, высокочастотной торговле (HFT), ручной фиксации или использовании фиксированных политик я отключаю их, чтобы избежать накладных расходов и джиттера. На этапах тестирования я работаю итеративно: измеряю, принимаю решение, повторяю проверьте. Я стараюсь упростить настройку, документирую каждое изменение и отслеживаю его влияние с помощью надежных показателей. Таким образом, я использую преимущества аппаратного обеспечения NUMA, избегая ненужных Риски принять.

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

Балансировка NUMA на современном серверном оборудовании под Linux в центре обработки данных
Серверы и виртуальные машины

Балансировка NUMA в Linux: отключить или оставить включенной?

Узнайте, как NUMA Balancing влияет на производительность Linux на современном серверном оборудовании и в каких случаях следует отключить или оставить эту функцию включенной. Тема: NUMA Balancing.

Серверная стойка в центре обработки данных с визуализированным управлением хранением данных в Linux и структурами Slab
Технология

Понимание аллокатора Slab в ядре Linux: эффективное управление памятью для небольших объектов

Узнайте, как аллокатор Slab в Linux оптимизирует память ядра, уменьшает фрагментацию и эффективно управляет небольшими объектами. Идеально подходит для углубленного изучения внутреннего устройства ядра.

Серверная стойка с выделенными модулями оперативной памяти, иллюстрирующая кэш ZFS ARC в центре обработки данных
Серверы и виртуальные машины

Кэш ARC в ZFS: как правильно понимать потребление памяти

Узнайте, как работает кэш ARC в ZFS, почему высокое потребление оперативной памяти является нормальным явлением и как правильно настроить использование памяти для повышения производительности ZFS.