メモリ不足 killer によるブートストラップの失敗

みなさん、こんにちは。

Discourse を ./launcher rebuild app で更新したいと考えています。このコマンドは約 1 年間正常に動作していました。私は 2〜4 週間に一度、必要に応じて更新を行っています。

OS は Ubuntu 18.04.5 LTS です。

***@***:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.5 LTS
Release:        18.04
Codename:       bionic

今日、以下のエラーで停止してしまいました。

FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile' failed with return #<Process::Status: pid 726 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"assets_precompile", "cmd"=>["su discourse -c 'bundle exec rake themes:update assets:precompile'"]}
db6d1b1dd685de69942a3df05c9cbd622860faaa286b042635878519d5b69b7b
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.

そのメッセージの直前の最初のエラーは以下の通りです。

<--- JS stacktrace --->

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: 0xa04200 node::Abort() [node]
 2: 0x94e4e9 node::FatalError(char const*, char const*) [node]
 3: 0xb7978e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb79b07 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd34395  [node]
 6: 0xd46c01 v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 7: 0xd0c472 v8::internal::Factory::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [node]
 8: 0xd086c2 v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawArray(int, v8::internal::AllocationType) [node]
 9: 0xd08774 v8::internal::FactoryBase<v8::internal::Factory>::NewFixedArrayWithFiller(v8::internal::Handle<v8::internal::Map>, int, v8::internal::Handle<v8::internal::Oddball>, v8::internal::AllocationType) [node]
10: 0xf4ef4b v8::internal::OrderedHashTable<v8::internal::OrderedHashSet, 1>::Allocate(v8::internal::Isolate*, int, v8::internal::AllocationType) [node]
11: 0xf4f0df v8::internal::OrderedHashTable<v8::internal::OrderedHashSet, 1>::Rehash(v8::internal::Isolate*, v8::internal::Handle<v8::internal::OrderedHashSet>, int) [node]
12: 0x103eb98 v8::internal::Runtime_SetGrow(int, unsigned long*, v8::internal::Isolate*) [node]
13: 0x1401219  [node]
Aborted (core dumped)
rake aborted!
Errno::ENOENT: No such file or directory @ rb_file_s_size - /var/www/discourse/public/assets/discourse/tests/test_helper-a9cbc4e1abdd1f2e9afced86d051cbd63c2e224dafe782533646a01592cc1f42.js
/var/www/discourse/lib/tasks/assets.rake:290:in `size'
/var/www/discourse/lib/tasks/assets.rake:290:in `block (4 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `block in concurrent?'
/var/www/discourse/lib/tasks/assets.rake:281:in `block (3 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:272:in `each'
/var/www/discourse/lib/tasks/assets.rake:272:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `concurrent?'
/var/www/discourse/lib/tasks/assets.rake:269:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
I, [2021-04-26T13:10:13.996101 #1]  INFO -- : Downloading MaxMindDB...
Compressing Javascript and Generating Source Maps

I, [2021-04-26T13:10:14.018697 #1]  INFO -- : Terminating async processes
I, [2021-04-26T13:10:14.020721 #1]  INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid: 55
I, [2021-04-26T13:10:14.022854 #1]  INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 172
172:signal-handler (1619442614) Received SIGTERM scheduling shutdown...
2021-04-26 13:10:14.023 UTC [55] LOG:  received fast shutdown request
2021-04-26 13:10:14.030 UTC [55] LOG:  aborting any active transactions
2021-04-26 13:10:14.043 UTC [55] LOG:  background worker "logical replication launcher" (PID 64) exited with exit code 1
2021-04-26 13:10:14.045 UTC [59] LOG:  shutting down
2021-04-26 13:10:14.073 UTC [55] LOG:  database system is shut down
172:M 26 Apr 2021 13:10:14.122 # User requested shutdown...
172:M 26 Apr 2021 13:10:14.123 * Saving the final RDB snapshot before exiting.
172:M 26 Apr 2021 13:10:14.270 * DB saved on disk
172:M 26 Apr 2021 13:10:14.271 # Redis is now ready to exit, bye bye...

このエラーの後、Discourse は起動しなくなります。サーバーを再起動すれば Discourse は再び起動しますが、再度 rebuild app を実行すると同じエラーが発生します。

一緒に原因を特定していただけませんか?

よろしくお願いいたします。

サーバーの起動中にメモリ不足が発生しています。free -m の出力を共有していただけますか?

「いいね!」 1

@:~# free -m
total used free shared buff/cache available
Mem: 985 777 70 49 136 44
Swap: 2047 228 1819

ふむ、再起動後もメモリ不足になるのは気になりますね。最後のアップデート以降、追加で何かインストールした覚えもありません。

私も同じ問題に直面しています。Node.js 用のメモリが不足しています。
export NODE_OPTIONS="--max_old_space_size=4096 --some_other_option" を使用しましたが、効果はありませんでした。

再構築を試みた際にも同じスタックトレースが発生しました。比較的最近のインストールで、開発とテストにのみ使用しているため、まだ十分な空き容量があるはずです。

OS: Ubuntu 20.04.1 LTS
free -m の出力:

root@discourse-test-environment:/var/discourse# free -m
              total        used        free      shared  buff/cache   available
Mem:            981         136         581           0         263         698
Swap:          2047         113        1934
「いいね!」 1

1GB の最低要件に少し届いていません。スワップ領域を少し増やしてみるのは一案ですが、RAM の増設をお勧めします。

そのエラーが表示されている場合は、RAM の増設が必要です(スワップ領域の増設も考えられますが、RAM の方が望ましいです)。

「いいね!」 3

はい、その新しい動作の理由をお教えいただけますか?その設定では1年以上問題なく動作していました。Discourseは現在、過去と何が異なるのでしょうか?

「いいね!」 1

ご提案ありがとうございます。確かに少し奇妙ですね。通常、5ドルのDigital Ocean Dropletではデフォルトの2GBスワップファイルで事足りていました。最新のアップデートでこれが一般的になるかどうか、様子を見てみます。

ともあれ、別のファイルにスワップ領域を大幅に増設(4GB)しました

しかし、アップグレードは依然として失敗しました。おそらく、追加のRAMが必須なのでしょう。現時点でトピック1件、ユーザー1名しかいないインスタンスなので、これは予想外でした。また、Discourseがスワップを利用するように設定する必要があるのか、それともデフォルトで利用可能なのかについても興味があります。

新しい free -m の出力は以下の通りです。

              total        used        free      shared  buff/cache   available
Mem:            981         138         576           0         266         703
Swap:          6143         109        6034
「いいね!」 1

はい、私も 1 vCPU と 1GB の vRAM を搭載した Digital Ocean Droplet を使用しています :slight_smile:

「いいね!」 1

スワップメモリを3GBに増設しましたが、同じエラーが発生し、まだ動作しません。

「いいね!」 1

私のテストインスタンスは、RAM とスワップを合わせて 2.5GiB だけで再構築可能です。ただし、あなたのインスタンスはそれ以上のリソースを必要としている可能性があります。

プラグインはインストールされていますか?コンパイル中にいずれかのプラグインが大量のメモリを消費しているのではないかと推測されます。

プラグインなしで再構築し、問題が解決するか確認していただけませんか?

ご返信ありがとうございます。

気になったのですが、RAM とスワップの内訳はどのようになっていますか?また、両方の「空き」容量だけをカウントしているのでしょうか、それともスワップファイルの総サイズとインスタンスの総 RAM を合計したものを指しているのでしょうか?

ああ、もちろんですね。Discourse OpenID Connect 認証プラグイン のインストールを検討していたことを言い忘れました。

現在、Data Explorer プラグイン も既にインストールされています。


  • Data Explorer と Docker Manager のみで再度試しましたが、以前共有したのと同じスタックトレースが表示され、成功しませんでした。
  • プラグインなし(Docker Manager のみ)で再度試しましたが、再構築は依然として失敗しました。

ConnectID プラグインの追加を試みる以外、初期インストール以降に変更を加えていないため、引き続き調査を続けます。

Trouble with `tests/test_helper`? - #2 で、関連するかもしれない問題が発生しています。

プラグインなしでアプリを再ビルドしましたが、変化はありません。同じエラーが発生します。

これは理解できませんが、バグのようです。このサイト上でブートストラップを実行しようとしています。非標準のプラグインは使用していません。アセットを一つのバケットから別のバケットへ移動させただけで、すべて正常に動作していました。UX に表示されないようにするために、DISCOURSE_S3_UPLOAD_BUCKET を ENV に追加するもう一度のリビルドを行っていました。最初に失敗した際、その行をコメントアウトし、3 日前に機能していた同じ設定でもう一度試しました。


Done compressing embed-application-9cef8308c816fc1d83137e63d6c556c6cc2b68fe2b6e5ce16cca6766ba2c0ae4.js : 0.17 secs

844614.350963717 Compressing: discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js
terser '/var/www/discourse/public/assets/discourse/tests/_test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js' -m -c -o '/var/www/discourse/public/assets/discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js' --source-map "base='/var/www/discourse/public/assets/discourse/tests',root='/assets/discourse/tests',url='https://CORRECT_CDN_ADDRESS.b-cdn.net/assets/discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js.map'"
Killed
rake aborted!
Errno::ENOENT: No such file or directory @ rb_file_s_size - /var/www/discourse/public/assets/discourse/tests/test_helper-8590b31b8e73c4172aeea4a4a6bd1930ccbce2547a20d831a30d457ba092a631.js
/var/www/discourse/lib/tasks/assets.rake:290:in `size'
/var/www/discourse/lib/tasks/assets.rake:290:in `block (4 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `block in concurrent?'
/var/www/discourse/lib/tasks/assets.rake:281:in `block (3 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:272:in `each'
/var/www/discourse/lib/tasks/assets.rake:272:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/assets.rake:181:in `concurrent?'
/var/www/discourse/lib/tasks/assets.rake:269:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
I, [2021-04-26T18:38:36.072881 #1]  INFO -- : Updating Discourse Loading Slider...
Downloading MaxMindDB...
Compressing Javascript and Generating Source Maps

CDN の URL に何か問題があるのかと疑問に思いましたが、上記のすべての行にはそれが含まれており、正常に動作していました。

これは、彼らのテーマに壊れた CSS があることを意味するのでしょうか?もしそうなら、痛いですね。マスターテーマには一部の CSS しか含まれていません。また、これらのコンポーネントもあります:https://github.com/discourse/DiscoTOC.git および https://github.com/davidtaylorhq/discourse-loading-slider.git

これは最小サイズのドロプレットですか?そのファイルは terser による圧縮が難しく、メモリ負荷が高まるようです。

おお、予想より小さいですね。これは数年前に皆さんが立ち上げたサイトだと思います(まだ自前のインフラではない段階でサイトを運営していた頃です)。

root@community:/var/discourse# free -h
              total        used        free      shared  buff/cache   available
Mem:           1.9G        1.2G        101M        259M        655M        354M
Swap:          2.0G        1.2G        773M

あ、なるほど。2GB の DigitalOcean ドロップレットですね。コントロールパネルへのアクセス権もあります。4GB へのアップグレードと、AMD への移行が必要だと伝えましょう。

編集:でも、これが単にその 1 つのファイルを圧縮するためだけなら、2GB のドロップレットで十分ではないでしょうか?

このテストヘルパーファイルは圧縮に非常に負荷をかけます。

  • UglifyJS はこれを圧縮するために 1.5GB の RAM を使用します。
  • Terser は 1GB 強を使用し、40 秒かかります。比較のため、同じサーバーで Ember+jQuery を処理した場合、所要時間は 8 秒です :scream:

@eviltrout 本番環境にこのファイルを置くべきでしょうか?

ああ、これは @Osama のこの変更から来ているようです。

-rw-r--r-- 1 discourse discourse  14M Apr 26 19:13 _test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js
-rw-r--r-- 1 discourse discourse 6.6M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js
-rw-r--r-- 1 discourse discourse 1.1M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js.br
-rw-r--r-- 1 discourse discourse 1.5M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js.gz
-rw-r--r-- 1 discourse discourse 5.7M Apr 26 19:14 test_helper-f4c4b5bf0657eab910d85b9a65b4bddbbbe2ce2ba603b17fe11b3d633d324e34.js.map
「いいね!」 8

参考までに追加しますが、2 つのテーマコンポーネントを削除しても、ビルドの失敗は続いています。そのため、現在はデフォルトの Light テーマのみを使用しています。

また、この出力はどこからのものでしょうか?私も側で確認・デバッグしたいので。これは ./launcher rebuild app の詳細オプションのようなものですか?

この問題を正しく修正するには少し時間がかかるため、当面はその変更を元に戻します。

「いいね!」 9