Предварительная компиляция ассетов занимает 20 минут

Я пересобираю образ на Digital Ocean droplet, и что-то занимает вечность:

I, [2024-01-10T09:47:14.854311 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile'
Node.js heap_size_limit (492.75) меньше 2048 МБ. Устанавливаю --max-old-space-size=2048.
[WARN] (broccoli-terser-sourcemap) Минификация "assets/admin.js" заняла: 25461 мс (более 20 000 мс)
[WARN] (broccoli-terser-sourcemap) Минификация "assets/plugins/chat.js" заняла: 47818 мс (более 20 000 мс)
Очистка временных файлов
Упаковка ресурсов
I, [2024-01-10T10:06:07.644096 #3264]  INFO -- : Запись /var/www/discourse/public/assets/break_string-cc617154cd957804f2f6a1f3bc68258c9cdca3d4b9a322bf777d145fed04790e.js

У droplet 1 ГБ оперативной памяти, и в остальном Discourse работает нормально. Я что-то делаю не так? Можно ли что-то сделать, чтобы ускорить пересборку? Спасибо!

Думаю, это сейчас сильно ограничит вас по памяти.

Дело дошло до того, что я бы фактически рекомендовал минимум 4 ГБ для экземпляра Discourse (плюс файл подкачки!) (даже с 2 ГБ + 2 ГБ подкачки обновления в интернете оказываются мучительно медленными).

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

Стандартных 1 ГБ ОЗУ достаточно для небольших сообществ Discourse. Для более крупных сообществ мы рекомендуем 2 ГБ ОЗУ.

Мы знаем, откуда возникает нехватка памяти на этом этапе? Возможно, можно пожертвовать коэффициентом сжатия или чем-то подобным, чтобы снизить требования к памяти?

Это исходит от ember-cli.

Вы уже сталкиваетесь с компромиссом между временем и пространством (нехватка памяти приводит к увеличению времени выполнения процесса).

Связанная тема:

Думаю, для следующего обновления на моих двух серверах я воспользуюсь гибкостью хостинг-провайдера: перед обновлением перенесу серверы на больший объём оперативной памяти, а сразу после — обратно к текущему минимальному конфигу. Это добавит немного дополнительного времени простоя, но если пересборка пройдет значительно быстрее, в итоге это может оказаться выгодным решением. Дополнительные расходы составят менее 1 доллара или, возможно, даже всего 1 цент за час дополнительной оперативной памяти (в моём случае — с $6 в месяц до $12 в месяц, при почасовой оплате в Digital Ocean по 1 и 2 цента соответственно).

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

Надеюсь, что это также снизит нагрузку на меня.

Возможно, я даже решу увеличить объём памяти с 1 ГБ до 8 ГБ, что обойдётся дополнительно в 6 центов в час. Это даст мне возможность временно удалить файл подкачки и облегчить нехватку дискового пространства.

Всё достигает пика во время обновлений — в остальное время текущая минимальная конфигурация всё ещё кажется достаточной.

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

Это здорово! Кто ваш хостинг-провайдер?

В одном случае — Digital Ocean (1 ГБ ОЗУ), в другом — Hetzner (2 ГБ ОЗУ).

Оба позволяют временно увеличивать объем оперативной памяти (RAM) в режиме онлайн без остановки?

Или нужно переносить данные между «дроплетами»/экземплярами?

Или достаточно просто перезагрузки?

Нет,

Это остановка — изменение размера — запуск — восстановление — остановка — возврат к исходному размеру — запуск.

Хорошо, но всё ещё на месте. Это отличный вариант, но да, лишние хлопоты… и простои.

Учитывая, что время пересборки на машине с 1 ГБ памяти занимает так много, можно сразу поступить так, ведь в любом случае она будет недоступна в течение 30 минут!

И, конечно, если вы готовы на это, то даже временное обновление до машины с 16 ГБ памяти может оказаться приемлемым по стоимости :slight_smile:

Я подозреваю, что многие сочтут своё время более ценным и, вероятно, стоит подумать о постоянном варианте с 4 ГБ и более.

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

Конечно, если у вас нет проблем с расходами, выбирайте достаточно мощный экземпляр!

Просто для справки: я только что обновил два своих форума, и оба обновления заняли менее часа. В обоих случаях я временно увеличил объём оперативной памяти до 8 ГБ, а затем снова уменьшил. Этот конкретный этап занял около 5 минут при (временных) 4 ядрах CPU и 8 ГБ RAM.

I, [2024-01-10T16:07:58.323464 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile'
110:M 10 Jan 2024 16:08:52.047 * 100 изменений за 300 секунд. Сохранение...
110:M 10 Jan 2024 16:08:52.048 * Фоновое сохранение запущено процессом 3276
3276:C 10 Jan 2024 16:08:52.384 * База данных сохранена на диск
3276:C 10 Jan 2024 16:08:52.386 * Fork CoW для RDB: текущий 1 МБ, пик 1 МБ, средний 0 МБ
110:M 10 Jan 2024 16:08:52.449 * Фоновое сохранение завершено успешно
Очистка временных файлов
Упаковка ассетов
Обновления базы IP MaxMind требуют лицензии
Пожалуйста, установите DISCOURSE_MAXMIND_LICENSE_KEY на значение, сгенерированное вами на https://www.maxmind.com
Обновления базы IP MaxMind требуют лицензии
Пожалуйста, установите DISCOURSE_MAXMIND_LICENSE_KEY на значение, сгенерированное вами на https://www.maxmind.com
I, [2024-01-10T16:12:14.362017 #3300]  INFO -- : Запись /var/www/discourse/public/assets/break_string-cc617154cd957804f2f6a1f3bc68258c9cdca3d4b9a322bf777d145fed04790e.js

Здесь видно, что ember (колонка 12) использует 2,5 ГБ RAM (колонка 6) и более одного ядра CPU (колонка 3)

# ps auxfc|egrep -A29 containerd
root      1097  0.2  0.5 1510892 44924 ?       Ssl  16:00   0:01 containerd
root      4507  0.1  0.0 717892  7556 ?        Sl   16:03   0:00  \_ containerd-shim
root      4530  0.1  0.3 312292 30512 ?        Ssl  16:03   0:00      \_ pups
systemd+  4609  0.0  0.3 213236 28608 ?        S    16:03   0:00          \_ postmaster
systemd+  4617  0.0  0.8 213340 67288 ?        Ss   16:03   0:00          |   \_ postmaster
systemd+  4618  0.0  0.0 213236  5876 ?        Ss   16:03   0:00          |   \_ postmaster
systemd+  4619  0.0  0.1 213236 10076 ?        Ss   16:03   0:00          |   \_ postmaster
systemd+  4620  0.0  0.1 213904  8860 ?        Ss   16:03   0:00          |   \_ postmaster
systemd+  4621  0.0  0.0  68004  5592 ?        Ss   16:03   0:00          |   \_ postmaster
systemd+  4622  0.0  0.0 213796  7100 ?        Ss   16:03   0:00          |   \_ postmaster
message+  4682  0.2  0.4  87976 35724 ?        Sl   16:03   0:00          \_ redis-server
1000      7722  1.1  0.0      0     0 ?        Z    16:07   0:01          \_ esbuild <defunct>
root      7736  0.0  0.0   2476   520 ?        S    16:07   0:00          \_ sh
root      7737  0.0  0.0   9296  4156 ?        S    16:07   0:00          |   \_ su
1000      7738  8.3  0.0   2476   580 ?        Ss   16:07   0:12          |       \_ sh
1000      7835  0.4  0.9 929524 78416 ?        Sl   16:08   0:00          |           \_ node
1000      7857  0.0  0.0   2484   524 ?        S    16:08   0:00          |               \_ sh
1000      7858  156 30.5 67413228 2491796 ?    Sl   16:08   3:37          |                   \_ ember
1000      7876 39.0  1.7 11486300 145476 ?     Ssl  16:08   0:44          |                       \_ node
1000      7882 36.7  1.5 11466956 122648 ?     Ssl  16:08   0:41          |                       \_ node
1000      7889 37.1  4.1 11647592 340908 ?     Ssl  16:08   0:42          |                       \_ node
1000      7761  1.5  0.0      0     0 ?        Z    16:08   0:02          \_ esbuild <defunct>

Вероятно, для меня хватило бы и 4 ГБ RAM, но, как отмечено, вся эта операция стоила всего несколько центов. (Теперь я вижу, что мог бы выбрать более быстрые процессоры за дополнительный цент.)

Редактирование: я сделал резервную копию перед началом и ещё одну после завершения работы, разница во времени составила 35 минут. Таким образом, время простоя, видимое пользователями, не превысило этого значения.

Редактирование: обратите внимание, что в панели управления Digital Ocean указано, что операция изменения размера может занимать до 1 минуты на каждый ГБ данных на диске — в моём случае это было всего 14 ГБ, и, как оказалось, каждое изменение размера заняло лишь 2 минуты. Однако, если у вас на инстансе очень много данных, этот процесс изменения размера может занять больше времени. (С другой стороны, если у вас очень много данных, возможно, вы и не пытаетесь запускать систему с менее чем 4 ГБ RAM.)

В некоторых случаях 4 ГБ ОЗУ всё ещё недостаточно. Например, у меня есть песочница с 8 ГБ ОЗУ, практически без трафика, но она настроена как мультисайт, чтобы можно было иметь 5 временных песочниц. Сегодня пересборка не удалась из-за ошибки 137 (нехватка памяти), хотя я уже пробовал трюк, который предложил @richard выше. Однако, чтобы избавить себя от необходимости делать это каждый раз, я создал файл подкачки большего размера (4 ГБ), что, похоже, позволило пересборкам выполняться на данный момент. Кажется, что за последний год мы просто обновляем серверы, потому что пересборки Discourse по какой-то причине стали требовать всё больше оперативной памяти.

Интересно. У вас есть настройки ядра, как описано в мнении MKJ о конфигурации развертывания Discourse?

(Всегда полезно иметь файл подкачки (swap) — 2 ГБ, 4 ГБ или сколько позволит свободное место на диске. У меня минимальный swap, так как у меня минимальное место на диске.)

Подумав об этом, понимаю, что польза от такого подхода ограничена только полной переустановкой — в конфигурации 2+2 я сейчас не могу использовать обновление «на лету» :frowning: … и, думаю, мне не придётся выполнять эту танцу с обновлением/понижением только ради обновления, например, одного плагина …

Лично я считаю, что единственный выход — это постоянное повышение объёма ОЗУ хотя бы до 4 ГБ …

Примечание: я не собираюсь ныть по поводу необходимости идти в ногу со временем … но, возможно, нам стоит начать отражать реальность в документации и рекомендациях для администраторов?

К сожалению, это делает Discourse немного менее доступным для новых пользователей, особенно для молодых людей :thinking:

На самом деле я поддерживаю эту идею: оставить текущую минимальную рекомендованную конфигурацию в качестве целевой и поискать способы оптимизации кода или изменения в исходных компонентах, чтобы держать ситуацию под контролем. Если минимальная конфигурация теперь будет стоить в два раза дороже, это станет серьёзным изменением в предложении. Именно поэтому я где-то уже высказывал мнение, что чрезмерные требования к памяти — это баг.

Теперь при попытке обновиться до последней версии я получаю ошибку обновления:

...[@embroider/webpack]
Killed
error Command failed with exit code 137.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Docker Manager: FAILED TO UPGRADE
#<RuntimeError: RuntimeError>
/var/www/discourse/plugins/docker_manager/lib/docker_manager/upgrader.rb:210:in `run'
/var/www/discourse/plugins/docker_manager/lib/docker_manager/upgrader.rb:111:in `upgrade'
/var/www/discourse/plugins/docker_manager/scripts/docker_manager_upgrade.rb:19:in `block in <main>'
/var/www/discourse/plugins/docker_manager/scripts/docker_manager_upgrade.rb:6:in `fork'
/var/www/discourse/plugins/docker_manager/scripts/docker_manager_upgrade.rb:6:in `<main>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/railties-7.0.5.1/lib/rails/commands/runner/runner_command.rb:43:in `load'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/railties-7.0.5.1/lib/rails/commands/runner/runner_command.rb:43:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/thor-1.2.2/lib/thor/command.rb:27:in `run'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:127:in `invoke_command'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/thor-1.2.2/lib/thor.rb:392:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/railties-7.0.5.1/lib/rails/command/base.rb:87:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/railties-7.0.5.1/lib/rails/command.rb:48:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/railties-7.0.5.1/lib/rails/commands.rb:18:in `<main>'
<internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
<internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
bin/rails:18:in `<main>'
Spinning up 1 Unicorn worker(s) that were stopped initially

Правильно ли я понимаю, что это ошибка нехватки памяти? Значит ли это, что серверы с 1 ГБ ОЗУ официально больше не поддерживаются?

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

Редактирование: для ясности — память = RAM + swap. RAM работает быстро, а swap — дёшев.