에셋 사전 컴파일에 20분 소요

Digital Ocean 드롭렛에서 이미지를 다시 구축하고 있는데, 어떤 작업이 너무 오래 걸립니다:

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

드롭렛은 1GB의 RAM을 갖추고 있으며, 그 외에는 Discourse가 정상적으로 작동합니다. 제가 무언가를 잘못하고 있는 걸까요? 재구축 속도를 높이기 위해 할 수 있는 일이 있을까요? 감사합니다!

이제 메모리가 매우 부족할 것 같습니다.

실제로 Discourse 인스턴스의 경우 최소 4GB(스와프 포함!)를 권장할 정도가 되었습니다. (2GB + 2GB 스와프를 사용하더라도 온라인 업데이트가 너무 느려서 고통스럽습니다).

감사합니다! 불행히도 그 가격은 제가 업데이트 시에만 체감할 수 있는 개선 사항에 비해 약 4배나 비쌉니다. 또한 클라우드 설치 가이드에는 여전히 다음과 같이 적혀 있습니다:

1 GB의 기본 RAM은 작은 Discourse 커뮤니티에서 잘 작동합니다. 더 큰 커뮤니티에는 2 GB의 RAM을 권장합니다.

이 단계에서 메모리 압박이 어디서 오는지 알고 있을까요? 압축 비율이 낮아지는 등의 단점을 감수하고 메모리 요구 사항을 줄이는 것이 가능할까요?

ember-cli에서 발생하고 있습니다.

이미 시간과 공간의 트레이드오프를 경험하고 있습니다(메모리 공간 부족으로 인해 프로세스 실행 시간이 더 길어지는 것).

관련 주제:

다음에 두 서버를 업데이트할 때, 호스팅 제공업체의 유연성을 활용하여 업데이트 전에 더 큰 RAM으로 이주하고, 업데이트 직후 다시 현재 최소 구성으로 되돌리는 방법을 사용할 계획입니다. 이로 인해 다운타임이 약간 증가하지만, 재구축(rebuild) 속도가 훨씬 빨라진다면 전체적으로 이득이 될 수 있습니다. 추가 비용은 1시간당 추가 RAM에 대해 1달러 미만, 아마도 1센트에 불과할 것입니다 (제 경우, Digital Ocean에서 시간당 과금 기준으로 월 6달러에서 월 12달러로, 각각 1센트와 2센트입니다).

링크된 스레드에서 언급했듯이, 경우에 따라 재부팅이 도움이 되므로, 제 경우에는 OS 패키지를 업데이트하고 재부팅하기에 좋은 타이밍입니다.

이것이 저에게도 덜 부담이 되기를 바랍니다.

사실 1GB에서 8GB로 업그레이드하는 것을 선택할 수도 있습니다. 시간당 6센트가 추가되지만, 이를 통해 스왑파일을 일시적으로 삭제할 수 있는 자유를 얻고 디스크 공간 부족 문제를 완화할 수 있습니다.

모든 것이 업데이트 시점에 피크에 도달합니다. 그 외 시간에는 현재 최소 구성으로도 충분해 보입니다.

업그레이드 사이클당 6센트는 확실히 감당할 수 있습니다.

정말 멋지네요! 호스팅 제공사는 어디인가요?

한쪽은 Digital Ocean(1GB RAM), 다른 쪽은 Hetzner(2GB RAM)입니다.

두 서비스 모두 RAM을 일시적으로 온라인으로 인플레이스(in-place)로 증설할 수 있나요?

아니면 “드롭렛”/인스턴스 간에 데이터를 이동해야 하나요?

아니면 단순히 재부팅만 하면 되나요?

아니요,

종료 - 리사이즈 - 시작 - 재빌드 - 종료 - 원래대로 리사이즈 - 시작 순서입니다.

좋습니다. 하지만 여전히 인플레이스(in-place) 방식이네요. 훌륭한 옵션이지만, 그렇죠, 추가적인 번거로움과 .. 다운타임이 따릅니다.

1GB 머신에서 재빌드하는 데 시간이 많이 걸리니, 어차피 30분 정도는 다운될 테니까 이 방법을 선택하는 것이 나을 수도 있습니다!

그리고 물론, 그렇게 할 의향이 있다면 일시적으로 16GB 머신으로 업그레이드하는 것이 비용 측면에서 괜찮게 나올 수도 있습니다 :slight_smile:

많은 분들이 자신의 시간을 더 가치 있다고 생각할 것이며, 아마도 영구적으로 4GB 이상을 사용하는 것을 고려해야 할 것입니다.

확실히 비용과 시간 사이의 트레이드오프의 일부입니다. 제 경우, 업그레이드를 위해 1시간의 베이비시팅을 이미 계획해 두었고, 이 시스옵(시스템 관리) 절차를 완전히 알고 있으므로 시간은 이미 확보된 상태입니다. 시간이 좀 더 걸리더라도 월 운영 비용을 최대한 낮게 유지하는 것을 선호합니다. 물론 다른 분들은 다른 트레이드오프를 선택할 수 있겠죠.

물론 돈을 쓰는 것이 부담이 없다면, 넉넉한 크기의 인스턴스를 선택하는 것이 좋습니다!

참고로, 방금 두 개의 포럼을 업데이트했는데, 두 경우 모두 일시적으로 RAM을 8GB로 늘렸다가 다시 원래대로 되돌린 상태였습니다. 두 경우 모두 경과 시간이 1시간 이내로 완료되었습니다. 이 특정 단계는 (일시적으로) 4개 CPU와 8GB RAM 환경에서 약 5분 정도 걸렸습니다.

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

여기서 12번째 열에 있는 ember 프로세스가 6번째 열에 표시된 대로 2.5GB의 RAM을 사용하고 있으며, 3번째 열에 표시된 대로 CPU를 하나 이상 사용하고 있는 것을 볼 수 있습니다.

# 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>

제 경우에는 4GB RAM으로도 충분했을 것 같습니다. 하지만 언급했듯이 이 전체 작업은 몇 센트 정도의 비용에 불과했습니다. (이제 보니, 1센트 더 지불하면 더 빠른 CPU를 선택할 수 있었음을 알게 되었습니다.)

수정: 작업을 시작하기 전에 백업을 하나 하고, 작업이 완료된 후에도 백업을 하나 더 했습니다. 두 백업 사이의 간격은 35분이었습니다. 따라서 사용자가 체감한 다운타임은 그보다 길지 않았습니다.

수정: Digital Ocean 제어판에 따르면 리사이징 작업은 디스크의 데이터 용량 1GB당 최대 1분까지 걸릴 수 있다고 합니다. 제 경우 데이터가 14GB뿐이었고, 실제로는 리사이징마다 2분 정도 걸렸습니다. 하지만 인스턴스에 데이터가 매우 많다면, 이 리사이징 과정이 더 오래 걸릴 수 있습니다. (다시 말해, 데이터가 매우 많다면 아마도 4GB 미만의 RAM으로 실행하려 하지 않을 것입니다.)

일부 경우 4GB RAM은 여전히 충분하지 않습니다. 예를 들어, 저는 트래픽이 거의 없는 8GB RAM 샌드박스를 사용하고 있지만, 5개의 일회용 샌드박스를 허용하기 위해 멀티사이트 설정으로 구성되어 있습니다. 오늘 재구축이 에러 137(OOM)으로 인해 실패했고, 위에서 @richard가 제안한 트릭을 시도해 보았습니다. 그러나 매번 이런 번거로움을 겪지 않기 위해 더 큰 스왑(4GB)을 생성했는데, 이로 인해 당분간 재구축이 이루어지는 것 같습니다. 지난 1년 동안 서버를 계속 업그레이드하고 있는 것 같은데, 어떤 이유에서인지 discourse 재구축이 정말로 RAM을 많이 소모하고 있습니다.

흥미롭네요. MKJ’s Opinionated Discourse Deployment Configuration에 나와 있는 것과 동일한 커널 설정을 사용하고 계신가요?

(스왑은 항상 유용합니다. 2GB나 4GB 등, 사용 가능한 디스크 공간에 따라 적절히 설정하세요. 저는 디스크 공간이 적어서 최소한의 스왑만 설정해 두었습니다.)

이것에 대해 생각해보니, 그 이점은 사실상 전체 재빌드(full rebuild)에만 제한적으로 적용되는 것 같습니다. 현재 저는 2+2 구성에서 온라인 업그레이드를 사용할 수 없거든요 :frowning: … 그리고 예를 들어 단일 플러그인 업데이트를 위해 이런 업그레이드/다운그레이드 절차를 반복할 것 같지는 않습니다 …

개인적으로는 최소 4GB로 영구적으로 업그레이드하는 것이 유일한 방법이라고 생각합니다 …

참고: 시대의 흐름에 맞춰야 한다는 사실에 대해 불평하는 것은 아닙니다 … 하지만 아마도 문서와 관리자 조언에서 현실을 더 잘 반영하기 시작해야 하지 않을까요?

불행히도 이는 디스코르스(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

이것이 메모리 부족 오류(OOM)라는 뜻인가요? 그렇다면 1GB 메모리를 가진 머신은 공식적으로 더 이상 지원되지 않는다는 뜻인가요?

실제로 메모리 부족 오류입니다. 디스크 공간이 충분하다면 스왑을 추가하는 것만으로 충분할 것입니다. 다만 RAM을 추가하는 경우보다 처리 시간이 더 오래 걸립니다. 호스팅 제공업체에서 RAM을 일시적으로 업그레이드했다가 나중에 원래대로 되돌릴 수 있는 옵션을 제공하는 경우가 있습니다. 이 경우 재부팅 몇 번, 짧은 다운타임, 그리고 소액의 추가 비용이 발생할 가능성이 높습니다.

수정: 명확히 하자면, 메모리 = RAM + 스왑입니다. RAM은 빠르고 스왑은 저렴합니다.