Не удалось обновиться с 3.2.0.beta3-dev до 3.2.0.beta3 из-за нехватки памяти

Здравствуйте,

Попытался обновить с версии 3.2.0.beta3-dev до 3.2.0.beta3, и это привело к сбою экземпляра Discourse из-за нехватки памяти во время сборки ассетов Ember. Попробовал выполнить ./launcher rebuild app, но результат тот же.

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb83f50 node::Abort() [ember]
 2: 0xa94834  [ember]
 3: 0xd647c0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [ember]
 4: 0xd64b67 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [ember]
 5: 0xf42265  [ember]
 6: 0xf5474d v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [ember]
 7: 0xf2ee4e v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [ember]
 8: 0xf30217 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [ember]
 9: 0xf113ea v8::internal::Factory::NewFillerObject(int, v8::internal::AllocationAlignment, v8::internal::AllocationType, v8::internal::AllocationOrigin) [ember]
10: 0x12d674f v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [ember]
11: 0x17035b9  [ember]
Aborted (core dumped)
error Command failed with exit code 134.
I, [2023-11-26T17:19:26.345389 #1]  INFO -- : yarn run v1.22.19
$ /var/www/discourse/app/assets/javascripts/node_modules/.bin/ember build
Environment: development
WARNING: ember-test-selectors: You are using an unsupported ember-cli-babel version. data-test properties are not automatically stripped from your JS code.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Экземпляр работает на сервере DigitalOcean с 1 ГБ ОЗУ для некоммерческой организации, поэтому я не могу позволить себе увеличить объем памяти. 1 ГБ — это минимальный размер для Discourse, и предыдущие версии работали без проблем. Есть ли идеи, как заставить его снова работать?

У вас есть Swap?

Что выведет команда

free -h
               всего       использовано    свободно      общий       буфер/кэш     доступно
Mem:           952Mi       321Mi           414Mi         3.1Mi       374Mi         631Mi
Swap:          2.0Gi       75Mi            1.9Gi

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

Возможно, стоит рассмотреть переезд на Hetzner, где предлагают конкурентные цены и 2 ГБ оперативной памяти в базовом тарифе.

Привет и добро пожаловать @andreid :slight_smile:

Мой тестовый сайт на DO с 1 ГБ памяти тоже недавно испытывал проблемы с нехваткой памяти во время пересборки. Я временно обновил его до 2 ГБ, чтобы просто завершить процесс.

Возможно, стоит сейчас обновить минимальные требования в документации до 2 ГБ ОЗУ?

Помню, что это происходило в прошлом году, и тогда были внесены некоторые исправления: JavaScript heap out of memory due to Ember CLI - #4 by JammyDodger. Не уверен, можно ли что-то сделать и на этот раз, но я спрошу. :+1:

Спасибо @RGJ и @JammyDodger, временное изменение размера сработало.

Добавление 1 ГБ файла подкачки функционально эквивалентно добавлению 1 ГБ оперативной памяти, если у вас есть свободное место на диске. (Скорее всего, процесс обновления займёт больше времени, но это вопрос производительности, а не функциональности. Ваша цель — избежать ситуации нехватки памяти.)

У меня есть дополнительная информация, которая может помочь смягчить проблему на стороне Discourse. Мой экземпляр (DigitalOcean ~1 ГБ droplet с 2 ГБ swap-памяти) недавно начал значительно дольше пересобираться и сообщать об одной и той же фатальной ошибке примерно в 3 случаях из 4 (удача, похоже, улучшается после запуска ./launcher cleanup, но у меня недостаточно данных для подтверждения этого).

Незадолго до ошибки исчерпания памяти в логах появляются следующие строки:

Node.js heap_size_limit (491.0) меньше 1024 МБ. Устанавливаем --max-old-space-size=1024.
Node.js heap_size_limit (491.0) меньше 2048 МБ. Отключаем параллелизацию Webpack с JOBS=0 для экономии памяти.

Я не эксперт в этой области, поэтому извините, если я что-то не так понял. Краткое исследование показывает, что ember-cli зависит от node.js, поэтому я считаю это важным. Флаг --max-old-space-size можно установить выше объёма оперативной памяти (в этом случае система просто будет использовать swap-память, что в данном случае приемлемо), поэтому, возможно, значение 1024 — это искусственное ограничение, которое больше не позволяет пересборкам Discourse укладываться в него.

Примечания: apparently --optimize-for-size — это флаг node.js, который помогает снизить потребление памяти (не уверен, используется ли он в Discourse/ember, возможно, уже используется), и существует anecdote о том, что сборщик мусора не включается для некоторых применений node.js, что может быть проблемой.

Если какая-либо из этих сведений актуальна и может быть управляема со стороны Discourse в части использования ember/node.js, возможно, стоит кому-то разобраться в этом. Если нет — без проблем, я воспользуюсь предложенным выше временным решением с обновлением до 2 ГБ. :slight_smile:

Это очень верное замечание! Сейчас мы увеличили этот лимит до 1024 МБ на машинах с небольшим объемом ОЗУ здесь. Мы, безусловно, могли бы поэкспериментировать с увеличением этого значения до 1500 или 2000 и посмотреть, поможет ли это.

Если у вас есть время и желание попробовать это самостоятельно, вы можете настроить это, добавив новую переменную в секцию env: вашего файла app.yml:

Редактирование: :warning: теперь это значение по умолчанию в Discourse. Настраивать вручную не нужно

  NODE_OPTIONS: "--max-old-space-size=2048"

Ах, отлично! Я сразу попробовал.

Так как фатальная ошибка возникает не каждый раз, а сборка в последнее время занимает около 25 минут (ранее 5–10), может пройти некоторое время, прежде чем я узнаю, решает ли увеличение этого числа проблему с памятью для данных конфигураций сервера.

Но я уже могу подтвердить, что два предупреждения о Node.js heap_size_limit больше не появляются в логе сборки, и моя первая сборка прошла успешно, что обнадеживает.

РЕДАКТИРОВАНИЕ: Мне удалось выполнить несколько сборок без проблем благодаря настройке NODE_OPTIONS, указанной выше в моём файле app.yml. Ура!

РЕДАКТИРОВАНИЕ 2: Это решение, вероятно, должно быть внедрено в Discourse путём увеличения этого магического числа (ссылка из поста Дэвида), чтобы другие машины с небольшим объёмом ОЗУ могли продолжать работать. Если кто-то, читающий это, знает, как это сделать, буду очень признателен. :slight_smile:

Мы столкнулись с этим же на https://caddy.community.

Мы несколько раз запускали ./launcher rebuild app, и процесс завершался с различными ошибками.

Сначала возникли проблемы с bundle install, который сообщал об ошибке при установке rbtrace (завершение с сообщением An error occurred while installing rbtrace (0.5.0), and Bundler cannot continue.).

Затем у нас возникла проблема с нехваткой памяти (OOM):

I, [2023-12-12T07:50:59.497921 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile'
Node.js heap_size_limit (1010.0) is less than 1024MB. Setting --max-old-space-size=1024.
Node.js heap_size_limit (1010.0) is less than 2048MB. Disabling Webpack parallelization with JOBS=0 to conserve memory.

<--- Last few GCs --->

[3683:0x5dab130]   279104 ms: Scavenge 981.3 (1037.1) -> 974.5 (1037.1) MB, 8.3 / 0.0 ms  (average mu = 0.699, current mu = 0.681) allocation failure; 
[3683:0x5dab130]   279136 ms: Scavenge 981.8 (1037.1) -> 975.0 (1037.1) MB, 8.0 / 0.0 ms  (average mu = 0.699, current mu = 0.681) allocation failure; 
[3683:0x5dab130]   282606 ms: Mark-sweep 994.8 (1050.6) -> 987.7 (1048.9) MB, 3316.1 / 0.0 ms  (average mu = 0.593, current mu = 0.501) allocation failure; GC in old space requested


<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb83f50 node::Abort() [ember]
 2: 0xa94834  [ember]
 3: 0xd647c0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [ember]
 4: 0xd64b67 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [ember]
 5: 0xf42265  [ember]
 6: 0xf5474d v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, [snip]
Aborted (core dumped)
error Command failed with exit code 134.

И наконец, запуск через ./discourse_doctor позволил в итоге преодолеть эту проблему (но почему? Возможно, из-за большего количества данных в кэше при последующих запусках, что снизило потребление памяти? :thinking:)

I, [2023-12-12T08:02:50.556442 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile'
Node.js heap_size_limit (1010.0) is less than 1024MB. Setting --max-old-space-size=1024.
Node.js heap_size_limit (1010.0) is less than 2048MB. Disabling Webpack parallelization with JOBS=0 to conserve memory.
110:M 12 Dec 2023 08:07:50.026 * 100 changes in 300 seconds. Saving...
110:M 12 Dec 2023 08:07:50.030 * Background saving started by pid 3706
3706:C 12 Dec 2023 08:07:51.292 * DB saved on disk
3706:C 12 Dec 2023 08:07:51.294 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
110:M 12 Dec 2023 08:07:51.334 * Background saving terminated with success
Purging temp files
Bundling assets

Однако это те сложности, с которыми нам не следовало сталкиваться. Надеемся, что в будущем ситуация улучшится.

Кстати:

# free -h
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       1.3Gi        87Mi       138Mi       593Mi       394Mi
Swap:         2.0Gi       337Mi       1.7Gi

Безусловно, именно поэтому мы собираем здесь информацию.

Похоже, что достаточно лишь настроить переменную окружения NODE_OPTIONS, так что, полагаю, либо зависимость приложения, либо изменение в V8 сделали наше предыдущее значение там нерабочим.

@david, как это выглядит?

Мне кажется, всё в порядке! Очевидно, что пересборки за 30+ минут всё ещё не идеальны, поэтому я надеюсь, что мы сможем улучшить ситуацию в ближайшем будущем. Но это кажется хорошим решением, чтобы остановить потери.

Стоит отметить, что увеличение версии PostgreSQL 16 по сравнению с версией 13 потребляет меньше места и значительно лучше оптимизировано. Это может снизить общий объем потребляемой оперативной памяти сервера.
https://smalldatum.blogspot.com/2023/10/postgres-versions-11-12-13-14-15-and-16.html

Сегодня я столкнулся с похожей проблемой при пересборке (два контейнера) на системе с подкачкой 2 ГБ + 2 ГБ для небольшого сайта.

Расширение подкачки до 2 ГБ + 4 ГБ на этот раз позволило решить проблему.

Кстати, в моём случае добавление

в файл app.yml не помогло. Помогло просто выполнение


sudo apt update
sudo apt upgrade