Нехватка памяти при пересборке с 4 ГБ swap?

Сегодня у меня несколько раз не удавалось выполнить запуск с двумя контейнерами из-за ошибок, подобных этой:

 ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL  Команда была завершена сигналом SIGKILL (принудительное завершение): ember build -prod"]

Кажется, после добавления swap-пространства в следующий раз всё заработало. Но здесь уже выделено 4 ГБ swap:

# free -h
               total        used        free      shared  buff/cache   available
Mem:           1.9Gi       1.1Gi       391Mi        45Mi       661Mi       830Mi
Swap:          4.0Gi       3.1Gi       911Mi

и ошибка всё ещё возникает. Если же остановить контейнер до начала запуска, всё проходит успешно.

Сборка загружает/использует готовые ресурсы? Или вы отключили эту функцию? (или внесли изменения в ядро, чтобы готовые ресурсы нельзя было использовать)

У вас много swap-памяти, но значительная её часть уже используется. Поскольку конфигурация с двумя контейнерами обеспечивает меньшее время простоя, возможно, текущий экземпляр сервера всё ещё работает и потребляет много памяти, возможно, из-за утечки.

Возможно, перезагрузка перед обновлением поможет. Попробуйте измерить использование swap-памяти до и после перезагрузки.

На одном из моих серверов наблюдается утечка или накопление памяти. По разумному предложению @RGJ я настроил cron-задачу на перезагрузку сервера каждые 7 дней в ранний понедельник утром (Западная Европа).

(Мы считаем, что знаем плагин, вызывающий проблему, но я пока не потратил время на выяснение причины утечки или накопления памяти).

Это похоже на убийство процесса из-за нехватки памяти (OOM): у меня доступно около 2 ГиБ ОЗУ, и при пересборке с двумя контейнерами наложение старого приложения и новой сборки приводит к исчерпанию памяти. Подкачка уже использует около 3 ГиБ до этапа инициализации, поэтому пик сборки Ember завершается сигналом SIGKILL. Остановка запущенного контейнера (или выполнение пересборки в одном контейнере) устраняет наложение и позволяет завершить процесс успешно. Следующий шаг — подтвердить это через dmesg, а затем либо перезапустить систему перед пересборками, либо выяснить, что вызывает рост использования подкачки со временем, либо добавить оперативную память (одна подкачка, похоже, не спасает, когда она уже сильно загружена).

Это выглядит не как проблема pnpm или Ember, а скорее как нехватка памяти на хосте.

Ключевой момент — сигнал SIGKILL. Обычно это означает, что в дело вмешалась операционная система и убила процесс (часто через механизм OOM killer), а не то, что ember build -prod завершился с ошибкой самостоятельно.

На небольших хостах процесс сборки Ember в продакшн-режиме может легко потреблять несколько гигабайт оперативной памяти. Даже если включен файл подкачки (swap), когда он почти полностью заполнен, ядро всё ещё может решить убить процесс node, который активно расходует память.

Несколько фактов, указывающих на это:

  • На момент сбоя файл подкачки уже сильно загружен.
  • Сбой гораздо чаще происходит, когда одновременно запущен другой контейнер.
  • Если остановить другой контейнер перед запуском bootstrap, точно такая же сборка завершится успешно.

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

Что помогло / может помочь:

  • Избегайте параллельного запуска нескольких процессов bootstrap или сборки ассетов.
  • Останавливайте другие контейнеры во время выполнения ember build -prod.
  • Ограничьте использование памяти Node (например, через NODE_OPTIONS=--max_old_space_size=1024), чтобы снизить пиковое потребление.
  • Если возможно, увеличение оперативной памяти хоста (4 ГБ и более) сделает процесс гораздо более стабильным.

Надеюсь, это поможет объяснить, почему сбои кажутся случайными, и почему остановка другого контейнера решает проблему.

Кажется, что больше swap-памяти не помешало бы. Вместо того чтобы смотреть на общий объём swap и говорить, что его много, посмотрите на свободный swap и убедитесь, что у вас есть запас для пересборки.

Также убедитесь, что вы включили оверкоммит.

Звучит как отличная идея! Вы перезагружаете весь сервер или только контейнер?

Назову это «решением», хотя бы ради порядка. :person_shrugging:

В любом случае, проблема повторилась на другом сервере с конфигурацией 2 ГБ + 3 ГБ. Тогда я перезагрузил web_only и попробовал снова — всё сработало как надо. Думаю, добавлю в свои инструменты перезагрузку web_only, возможно, если память достигнет какого-то порога «низкого уровня».

Я ничего не делал для отключения этой функции.

Я включаю это на машинах, которые настраиваю… и похоже, что на этой машине оно уже включено.

Спасибо всем за ваши идеи!

Весь сервер :sweat_smile:

Это не Windows, ради бога. :rofl:

Ох, как я помню те времена! :grimacing:

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