Pré-compilação de assets leva 20 minutos

Estou reconstruindo a imagem em um droplet do Digital Ocean e algo está demorando muito:

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) is less than 2048MB. Setting --max-old-space-size=2048.
[WARN] (broccoli-terser-sourcemap) Minifying "assets/admin.js" took: 25461ms (more than 20,000ms)
[WARN] (broccoli-terser-sourcemap) Minifying "assets/plugins/chat.js" took: 47818ms (more than 20,000ms)
Purging temp files
Bundling assets
I, [2024-01-10T10:06:07.644096 #3264]  INFO -- : Writing /var/www/discourse/public/assets/break_string-cc617154cd957804f2f6a1f3bc68258c9cdca3d4b9a322bf777d145fed04790e.js

O droplet tem 1 GB de RAM e, de resto, executa o Discourse perfeitamente. Estou fazendo algo errado? Posso fazer algo para acelerar a reconstrução? Obrigado!

1 curtida

Acredito que isso o deixará muito com restrição de memória agora.

Está chegando ao ponto em que eu realmente recomendaria um mínimo de 4 GB para uma instância do Discourse (mais swap!) (mesmo com 2 GB + 2 GB de swap, acho as atualizações online dolorosamente lentas).

3 curtidas

Obrigado! Infelizmente, isso é cerca de quatro vezes o preço por uma melhoria que eu provavelmente só sentiria durante as atualizações. Além disso, o guia de instalação na nuvem ainda diz:

O padrão de 1 GB de RAM funciona bem para pequenas comunidades Discourse. Recomendamos 2 GB de RAM para comunidades maiores.

Sabemos de onde vem a pressão de memória nesta etapa? Talvez fosse possível trocar uma taxa de compressão pior ou algo assim por requisitos de memória reduzidos?

Vem do ember-cli.

Você já está experimentando uma troca entre tempo e espaço (a falta de espaço de memória faz com que o processo demore mais).

3 curtidas

Tópico relacionado:

1 curtida

Acho que para minha próxima atualização em meus dois servidores, usarei a flexibilidade do provedor de hospedagem para migrar para uma RAM maior antes de atualizar e migrar de volta para meu mínimo atual imediatamente depois. Há uma pequena quantidade de tempo de inatividade extra, mas se a reconstrução for muito mais rápida, pode ser uma vitória geral. A despesa extra deve ser inferior a US$ 1 ou talvez até mesmo 1 centavo, por uma hora de RAM extra (no meu caso, de US$ 6 por mês para US$ 12 por mês, cobrado por hora na Digital Ocean a respectivamente 1 centavo e 2 centavos).

Como observado no tópico vinculado, às vezes uma reinicialização é útil de qualquer maneira, então é um bom momento para atualizar os pacotes do sistema operacional e reiniciar, para mim.

Espero que isso cause menos desgaste em mim também.

Na verdade, posso optar por aumentar de 1 GB para 8 GB, o que custará 6 centavos extras por hora, para me dar a liberdade de excluir meu arquivo de swap temporariamente e aliviar a falta de espaço em disco.

Tudo atinge o pico na hora da atualização - nos intervalos, a configuração mínima atual ainda parece ser adequada.

Eu certamente posso pagar 6 centavos por ciclo de atualização.

4 curtidas

Isso é muito legal! Quem é o seu provedor de hospedagem?

Digital Ocean em um caso (1G RAM), Hetzner no outro (2G RAM).

Ambos permitem aumentos temporários de RAM online e no local?

Ou você precisa alternar entre “droplets”/instâncias?

Ou apenas uma reinicialização?

Não,

É desligar - redimensionar - ligar - reconstruir - desligar - redimensionar de volta - ligar

4 curtidas

OK, mas ainda no local. Essa é uma ótima opção, mas sim, trabalho extra… e tempo de inatividade.

Dado que o tempo de reconstrução em uma máquina de 1 GB leva tanto tempo que você pode muito bem fazer isso, porque ela ficará inativa por 30 minutos de qualquer maneira!

E claro, se você estiver preparado para fazer isso, até mesmo um upgrade temporário para uma máquina de 16 GB pode funcionar bem em termos de custo :slight_smile:

Suspeito que muitos considerarão seu tempo mais valioso e provavelmente deveriam começar a pensar em 4 GB + em uma base permanente.

1 curtida

É certamente parte de uma troca entre custo e tempo. Pessoalmente, já me comprometi a fazer uma hora de “babysitting” para as atualizações, e sei perfeitamente como fazer essa dança de sysadmin, então o tempo já está reservado. Prefiro manter o custo mensal de execução o mais baixo possível, mesmo que isso me leve algum tempo - outros terão outras trocas.

Com certeza, se gastar dinheiro for fácil, pegue uma instância confortavelmente grande!

1 curtida

Apenas para referência, acabei de atualizar meus dois fóruns, ambos concluídos em menos de uma hora, em ambos os casos redimensionei temporariamente para 8G de RAM e de volta. Esta etapa específica levou cerca de 5 minutos, com (temporariamente) 4 CPUs e 8G de 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 changes in 300 seconds. Saving...
110:M 10 Jan 2024 16:08:52.048 * Background saving started by pid 3276
3276:C 10 Jan 2024 16:08:52.384 * DB saved on disk
3276:C 10 Jan 2024 16:08:52.386 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 0 MB
110:M 10 Jan 2024 16:08:52.449 * Background saving terminated with success
Purging temp files
Bundling assets
MaxMind IP database updates require a license
Please set DISCOURSE_MAXMIND_LICENSE_KEY to one you generated at https://www.maxmind.com
MaxMind IP database updates require a license
Please set DISCOURSE_MAXMIND_LICENSE_KEY to one you generated at https://www.maxmind.com
I, [2024-01-10T16:12:14.362017 #3300]  INFO -- : Writing /var/www/discourse/public/assets/break_string-cc617154cd957804f2f6a1f3bc68258c9cdca3d4b9a322bf777d145fed04790e.js

Aqui vemos que o ember (coluna 12) está usando 2,5G de RAM (coluna 6) e mais de uma CPU (coluna 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>

Provavelmente 4G de RAM teriam sido suficientes para mim, mas como observado, todo esse processo custou apenas alguns centavos. (Vejo agora que eu poderia ter escolhido CPUs mais rápidas por um centavo extra.)

Editar: Fiz um backup antes de começar e outro depois que o trabalho foi concluído, e eles estavam separados por 35 minutos. Portanto, o tempo de inatividade visto pelos usuários não foi maior do que isso.

Editar: note que o painel de controle da Digital Ocean diz que a operação de redimensionamento pode levar até 1 minuto por GB de dados no disco - no meu caso, apenas 14G e, como se viu, apenas 2 minutos para cada redimensionamento. Mas se você tiver uma grande quantidade de dados na instância, essa dança de redimensionamento pode levar mais tempo. (Por outro lado, se você tem uma grande quantidade de dados, talvez não esteja tentando executar com menos de 4G de RAM)

3 curtidas

4GB de RAM ainda não são suficientes em alguns casos. Por exemplo, tenho um sandbox com 8GB de RAM e praticamente sem tráfego, mas é uma configuração multissite para permitir ter 5 sandboxes descartáveis. A reconstrução hoje falhou devido ao Erro 137 (OOM) e eu tentei o truque que @richard sugeriu acima. No entanto, para me poupar do incômodo de fazer isso toda vez, criei um swap maior (4GB) que parece ter permitido as reconstruções por enquanto. Parece que estamos apenas atualizando servidores no último ano porque as reconstruções do Discourse estão realmente consumindo muita RAM por algum motivo.

2 curtidas

Interessante. Você tem as configurações do kernel conforme descrito em MKJ’s Opinionated Discourse Deployment Configuration?

(Sempre vale a pena ter swap, 2G ou 4G ou o que quer que o espaço livre em disco permita. Tenho swap mínima porque tenho espaço em disco mínimo.)

Pensando nisso, o benefício é realmente limitado a reconstruções completas - não posso usar atualizações online em uma configuração 2+2 :frowning: … e acho que não vou fazer essa dança de atualização/rebaixamento apenas para atualizar, por exemplo, um único plugin …

Pessoalmente, sinto que uma atualização permanente para pelo menos 4 GB é a única maneira …

Nota: Não estou reclamando por ter que acompanhar os tempos … mas talvez devêssemos começar a refletir a realidade na documentação e nos conselhos aos administradores?

Infelizmente, isso torna o Discourse um pouco menos acessível para pessoas novas, especialmente mais jovens embora :thinking:

1 curtida

Na verdade, estou a favor desta ideia: manter a configuração mínima recomendada atual como um alvo e procurar ajustes no código ou alterações upstream para manter as coisas sob controle. É uma grande mudança na oferta se a configuração mínima agora custar o dobro. É por isso que opinei em outro lugar que requisitos excessivos de memória são um bug.

2 curtidas

Agora estou recebendo falhas nas atualizações ao tentar atualizar para a versão mais recente:

...[@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

Imagino que este seja um erro de falta de memória? Isso significa que as máquinas de 1 GB estão oficialmente obsoletas?

De fato, esse é um erro de falta de memória. Se você tiver espaço em disco para adicionar swap, isso será suficiente, embora o processo leve mais tempo do que se você adicionasse RAM. Seu provedor de hospedagem pode oferecer a chance de atualizar a RAM temporariamente e depois reverter, o que provavelmente custará alguns reinícios, um pouco de tempo de inatividade e alguns centavos de custo extra.

Editar: para ser claro, memória = RAM + swap. RAM é rápida e swap é barato.

2 curtidas