Discourse 占用内存不多

你好!

我在 Docker 上运行 Discourse,但当内存使用过高时,它似乎从不使用交换空间(swap),导致程序崩溃,或者在我尝试重建时出现 fatal error: out of memory allocating heap arena map 错误。除非每隔几小时重启一次,否则似乎无法正常运行。

有人知道如何修复这个问题吗?

谢谢,
Kian

假设你使用的是 Linux,free -h 会显示什么?(最好是在重启后立即,以及错误发生前不久。)

2 个赞

也许 swappiness 被设置为 0 了?
cat /proc/sys/vm/swappiness

2 个赞

嗨!之前是 40,我现在已经设置为 60 了。

Screenshot_440

系统始终会缓存大量 RAM,即使 RAM 使用率很高,交换空间也从未被使用。

我认为输出中需要重点关注的两个部分是 5.5G 的可用内存和 0B 的已用交换空间。或者也许是 9G 的空闲交换空间。5.5G + 9G 能告诉你还有多少余量。用于缓冲区和缓存的内存量是动态的,绝不应导致短缺。

鉴于故障发生时间仅有几小时,我建议使用 vmstat 5 并捕获输出,以便你能看到最后的时刻。我过去曾使用 cron 任务,每 10 分钟运行一次 vmstat 5 5 并将结果写入日志文件。

如果是软件行为异常,它可能会迅速耗尽所有可用资源。在这种情况下,每隔几分钟记录一次 ps uax 以获取关键时刻的若干快照,可能会非常有用。

也有可能存在其他限制。想必这是在原生操作系统上进行的原生安装,没有其他程序运行,也没有特殊配置?

2 个赞

你好!
我该如何每隔10分钟将 vmstat 5 的输出写入日志?又该如何每隔几分钟将 ps uax 的输出写入日志?

是的,这是一个原生安装的 Ubuntu Server 18.04,只安装了 Apache、Docker 等常用软件。

我刚刚想起来,我还安装了 Varnish Cache,这解释了被缓存的 RAM 使用情况。但我不明白为什么 Discourse 不使用交换空间(swap)。我前几天通过 Docker 命令设置了它的交换空间限制,但似乎没有任何效果。

这里有一个简单实用的单行命令(当然,使用 cron 是更好的方式):

sh -c 'rm -f /tmp/stop; while [ ! -e /tmp/stop ]; do (date; uptime; free; ps faux; vmstat 5 5) >> /var/log/monitor.log; sleep 600; done' &

它将一直运行:若要停止,请执行 touch /tmp/stop
日志将出现在 /var/log/monitor.log 中——使用 tail -99 查看最新内容,或使用 less 分页浏览。你需要设法在日志中找到显示问题逐渐发展的部分。

感觉你在这里问错了问题。是 Linux 内核负责管理虚拟内存,包括缓冲区的使用和交换空间的使用。如果 free 命令报告交换空间已配置,那正是应有的状态,你无需做任何操作。

你真正的问题应该是:为什么我的 Discourse 运行不佳?为什么需要重启?以及为什么我会看到 fatal error

我非常建议你重命名此主题为:
为什么会出现“fatal error: out of memory allocating heap arena map”?

此外,我担心你似乎有几个不同的观察结果:

  • 有时 Discourse 会崩溃
  • 有时我在重建时看到“fatal error:… heap arena map”
  • 有时我需要每隔几小时就重启一次

目前还不清楚这些观察结果之间具体是如何关联的。

  • 是什么让你认为 Discourse 崩溃了?具体观察到了什么现象?
  • 每次重建时是否都会看到“fatal error:”?
  • 你为什么要进行重建?
  • 是什么促使你重启?你指的是重启服务器吗?

很希望能听到你的回答!

1 个赞

嗯,你具体做了什么?执行以下命令后:

docker stats --no-stream --no-trunc

MEM USAGE / LIMITMEM % 显示的内容是什么?

(在我的情况下,LIMIT 略低于机器的物理内存。这可能意味着容器内运行的任何进程都不太可能触发交换,即使几乎没有或根本没有使用交换空间,你也可能会看到某个进程因无法分配内存而失败。)

你好!
我认为 Discourse 已经崩溃了,因为访问该域名时显示 Nginx 502 Bad Gateway 错误。不过 Docker 容器仍在运行。

是的,除了偶尔发生的情况。

我重新构建了它,因为这通常能暂时解决 502 Bad Gateway 问题。

我还重启了服务器,看看能否修复该错误。这有时有效,但更可能的是无效,而重新构建通常能暂时解决问题。

我稍后也会提供错误日志。

当我运行 /var/log/monitor.log 并使用 tail -99 时,我收到以下错误:-bash: /var/log/monitor.log: 权限被拒绝。

(从您的截图中可以看到,名为“app”的容器内存限制为 7.8G,当前仅使用了 3%,这没问题。编辑:但它使用了 100% 的 CPU,这一点可能有些可疑。)

我们只需要查看该日志文件的末尾,因此
tail -199 /var/log/monitor.log
可能会提供我们所需的信息。不过,我们可能需要查看更多内容:或许您可以将日志文件压缩后附加,或通过其他方式分享。该日志文件有多大?
ls -l /var/log/monitor.log

我认为 100% 代表 1 个核心,因为系统运行正常。

log.txt|附件 (25.0 KB)
日志共 199 行。

monitor.txt (39.3 KB)
这是完整的日志:slight_smile:

谢谢。这一切看起来都很正常,但这只是一个单一快照。实际情况应该是每隔 10 分钟,日志中就会追加一个新的部分。请先等待,直到你发现 Discourse 出现问题的迹象,然后再分享最后几个部分。

我得说,我也不清楚到底发生了什么。

我注意到你的三个 Unicorn 进程占用了大量 CPU,但我不明白它们为什么会这样。

USER       PID %CPU %MEM     VSZ    RSS TTY  STAT START  TIME 
 COMMAND
x          434 51.9  2.8  443732 234144 ?    Sl   18:26  0:11  \\_ unicorn master -E production -c config/unicorn.conf.rb
x          662  103  3.6 8877408 301148 ?    Rl   18:26  0:08  |   \\_ discourse sidekiq
x          686 99.7  3.6 8873312 301916 ?    Rl   18:26  0:06  |   \\_ unicorn worker[0] -E production -c config/unicorn.conf.rb
x          731 94.3  3.6 8873312 294368 ?    Rl   18:26  0:05  |   \\_ unicorn worker[1] -E production -c config/unicorn.conf.rb
x          744 77.2  3.3 8873312 276788 ?    Rl   18:26  0:03  |   \\_ unicorn worker[2] -E production -c config/unicorn.conf.rb

你可以运行 top 并按 shift+m 按内存使用量排序,查看哪些进程占用了最多的内存。能否将结果发布在这里?