高重建内存需求:2025年4月版

看起来 2+2 可能已经不够用了……我正在管理一个相当普通的 Discourse 实例(没有大型/花哨的插件等),但从今天开始,它因为 ember 耗尽了所有可用的 RAM 和 swap,导致机器无响应而无法启动。添加另外 2GB 的 swap 允许启动完成,峰值 swap 使用量约为 2.5GB。

9 个赞

哎呀,这是@david的调查清单上的内容。

5 个赞

@david 已经进行了调查,我们确认目前 2GB 对于 docker 重建来说足够,但不足以让 web 升级程序正常工作。

我提出的一个想法是在 web 升级期间关闭所有 ruby 进程,以节省额外的 300-500MB,这样就能为 asset 预编译留出足够的空间。

对于自托管用户,我们很可能需要采取一种长期的解决方案,即分发已引导的容器,但这会打开潘多拉的盒子,因为 web 升级程序将如何实现这一点呢?我们不想挂载 docker 套接字……

这确实是个棘手的问题。

2 个赞

对我来说,事实并非如此。

这是将基础纯安装与实际情况进行比较吗?

确实,它并不完全一致。即使其他所有东西都关闭了,它仍然可能失败。

不幸的是,我们在这里正在与现代 JS 构建工具进行一场注定失败的战斗。它们都是为在现代开发人员机器上运行 8GB+ 内存而设计的,而不是在 1GB VPS 上 :cry:

我们确实有一些解决方案。例如:提供可以自动下载的预构建资产。我们面临的巨大挑战是插件,因为它们在每个人的网站上都不同,而现在它们与核心构建紧密集成。

但目前,与 Web UI 更新相比,进行完整的 CLI 重建的成功率应该更高。

8 个赞

和 Jagster 一样,2GB RAM + 2GB swap 对于我的命令行驱动的 Docker 重建来说实际上是不够的。进一步检查,此安装上的唯一插件是 docker_managerdiscourse-prometheus——我预计这两个插件都不会给 ember 带来意外的负载。

如果最低配置必须更改,那将很糟糕,但总比目前的情况好,即机器在每次升级时都会意外地卡死。

7 个赞

如果是这样,我认为最好还是稍微提高推荐的配置。就我个人而言,如果能让重建更可靠,增加 2 GB(甚至 4 GB)的交换空间也无妨——至少只要日常运行在 2-4 GB RAM(适用于中小型社区)下仍然可以正常进行。

2 个赞

确实,我最近在 4c 4g 实例上的初始安装失败了。Ed 建议创建一个交换文件。我找到了创建交换文件的帖子,并创建了一个 4g 的交换文件。现在在 Web 或 CLI 更新/升级中一切都按预期工作。

依我看,我们可能只需要接受 Discourse 比以前需要更多的 RAM。

3 个赞

zram 没道理吗?

我们刚刚合并了这个提交,希望能改善这种情况。请告知我们您的测试结果!(它将在接下来的约 30 分钟内进入 tests-passed)

在本地使用内存受限的 Docker 容器进行测试时,我现在可以使用 -m 1600m 成功构建。在此更改之前,我能达到的最低值是 -m 3000m

12 个赞

我进行了测试重建(全新安装),过程没有问题。现在该机器有 4GiB 的 RAM(Hetzner CAX11)和一个相同大小的交换文件,因此其限制肯定比上面提到的 2+2 GB 设置要小。然而,在整个构建过程中交换使用量很小,我看到的最高 RAM 使用量约为 3.1GB。大多数时候,它保持在 2GB 左右,所以看起来不算太糟(构建时间或多或少没有变化,即大约 8 分钟)。

4 个赞

我很想做一些受控的实验,进行干净的安装和重建,在各种设置下进行,特别是想看看运行 vm overcommit(如果有的话)有什么区别,但我恐怕一直没时间。

(没有 overcommit,一个大的 fork 进程在内存占用上会有一个瞬时的增加,这可能是致命的,并且不会显示在轮询监视器上。即使有 overcommit,内存增加也可能足够快,以至于在轮询(无论是 htop 还是 vmstat 还是其他什么)中都无法显示。)

我认为我从未见过有人主动说明他们是否启用了 overcommit,尽管在我看来,这是主机配置的一个重要方面。

1 个赞

我打赌大多数人不会。

我在我的安装中自动设置了它。但我仍然收到有关它的警告。

这里过量分配无关紧要,因为问题不在于进程过早被 OOM 杀死,而在于试图将十磅的分配内存塞进一个五磅的袋子里。

实际上无法在 overcommit_memory=2 的情况下运行 Discourse 重建,因为 ember(以及其他东西,毫无疑问)会预先分配大量的虚拟内存(我记得我看到的是大约 80GB),因此这总是会违反任何合理的 overcommit_ratio 设置。将 overcommit_memory 设置为 1 也无济于事,因为同样,问题不在于过于热情的 VMM 杀死进程,而在于 ember 编译器糟糕的内存管理。

1 个赞

我不太确定我是否完全同意你的分析!据我所知,overcommit 允许进程分配它们不使用的内存。这不仅仅是关于 OOM-killer 的行为。但正如我所说,我想做一些受控的实验,这是了解什么有效、什么无效的更好方法。

我有4GB的内存和许多插件(如果我没有意识到的话,没有交换文件)。你有多少插件,你认为仅仅4GB的内存够用吗?

部分正确,但即便如此,这也没有关系,因为本主题讨论的问题是进程分配它们 使用的内存,并且使用的内存超过了系统可用内存,这会导致客户可见的中断。

请确认在 @david 的更改之后,内存需求是否已降低?我们现在应该处于一个合理的状态。

下一个大的飞跃将是预编译和分布式预编译资源,这是一个相当大的变化,但一旦完成,它将消除互联网上的大量工作。

2 个赞

恕我直言,我不确定。我见过显示 fork 失败的日志文件。我们在本帖中说这是“内存需求”,但在我看来,这包括内核的虚拟内存策略。显然,一两个实验将表明我关于过量分配的说法是否正确。

那是一个没有任何插件的全新构建。我可以尝试启用一些插件的另一个构建,也许暂时禁用交换空间以确认构建是否成功(不过我可能要几天时间才有空做这个事情)。

2 个赞