如何最大限度地减少 SpamAssassin (spamd) 的内存使用

如何最大限度地减少 SpamAssassin (spamd) 的内存使用

我在 Debian 上使用 SpamAssassin(默认配置,禁用 Pyzor、AWL 和 Bayes,启用 sa-compile),每个 spamd 子进程在 32 位服务器上消耗大约 100 到 150MB 内存(大约 50MB 实际内存),在 64 位服务器上大约是这个数字的两倍(逻辑上足够)。通常有两个子进程,但在繁忙时可能会有五个(最多)正在运行。

我认为 200 到 600MB 的内存对于此任务来说是很大的。我想继续使用 SA 作为过滤结构的一部分,但要证明这么多内存的合理性变得越来越困难。

有什么方法可以减少每个子进程使用的内存量?(或者,使单个子进程如此之快,以至于我可以将最大子进程数设置为 2?)。我愿意考虑任何选项,包括那些会或可能导致准确度降低的选项。

我已经读过SA wiki 上的“内存不足问题”页面;那里没有任何用处。大于 5 MB 的邮件不会使用 SA 进行扫描。

答案1

我认为您误解了 Linux 报告内存使用情况的方式。当一个进程分叉时,它会产生第二个进程,该进程与原始进程共享大量资源。其中包括内存。但是,Linux 为此使用了一种称为写时复制 (COW) 的技术。这意味着每个分叉的子进程都将在内存中看到与原始进程相同的数据,但每当该数据发生变化(由子进程或父进程更改)时,更改都会被复制,然后才指向新位置。

在其中一个进程更改该数据之前,它们共享同一份副本。因此,我可以有一个使用 100MB RAM 的进程,并对其进行 10 次分叉。每个分叉进程都会显示正在使用的 100MB RAM,但如果您查看机器上的整体内存使用情况,它可能只显示正在使用的 130MB RAM(进程之间共享 100MB,加上几 MB 的开销,以及系统其余部分的另外十几或二十 MB)。

最后一个例子,我现在有一个盒子,里面有 30 个 Apache 进程在运行。每个进程都显示占用了 22MB 的 RAM。但是,当我运行免费-m为了显示我的整体 RAM 使用情况,我得到:

topher@crucible:/tmp$ free -m
             total       used       free     shared    buffers     cached
Mem:           349        310         39          0         24         73
-/+ buffers/cache:        212        136
Swap:          511         51        460

如您所见,此机器甚至没有足够的 RAM 来运行 30 个进程,每个进程都使用 18MB 的“实际”RAM。除非您真的用完了 RAM 或您的应用程序交换量很大,否则我不会担心。

更新:另外,请查看这个名为微电子,提及杰尔杜格尔在回答另一个关于Linux内存使用的问题时这里

答案2

使用sa-编译你也许能够提高许多规则的匹配速度。

答案3

这是我所做的。

我有一个设置,其中许多消息倾向于大致同时传递;对于一系列实验,我对复制到临时假脱机然后每五分钟由 cron 作业传递一次的消息运行 SA。

spamd会继续打印“也许你应该增加 max-children 参数”,并且我曾将其提高到 40,但是我的服务器消耗了所有的交换空间并崩溃了。

现在我已经实施了一种不同的机制,其中交付由 Procmail 锁定文件控制。由于这样做很简单,我只使用进程 ID 的最后一位数字,并使用 10 个子进程运行。我完全不确定这是否是最佳选择,但它已经帮助我避免了不时遇到的疯狂负载峰值。

LINEBUF=10240

# Grab last digit of PID for lockfile
PID=$$
:0
* PID ?? ()\/[0-9]$
{ D=$MATCH }
:0
* > 512000
{ SA="(too large)" }
:0Ew:/tmp/20spamc.$D
SA=| spamc -p 38783 -l -y

此外,我一开始就设定了spamd一些ulimit限制。这些数字是从http://svn.apache.org/repos/asf/spamassassin/trunk/contrib/run-masses除非我移除了ulimit -u限制。(不确定发生了什么。无论如何,32 都太小了。如果是 500 左右,我可以继续spamd运行一段时间,但最终会达到极限。)

ulimit -v 204800
ulimit -m 204800
ulimit -n 256
#ulimit -u 32

perl -T -I lib -w spamd --min-children 2 --max-children 10 --max-spare 5 etc etc

我想如果负载长时间过高的话,最终会导致交付失败,但到目前为止,似乎我已经设法将负载降低到可控水平;而且一堆交付失败仍然比机器耗尽交换要好得多。

答案4

几个月前我们也遇到过类似的情况。SpamAssassin 和 ClamAV 在托管服务器上占用了大量内存。我们本来可以选择为服务器添加更多内存,但事实证明,切换到 Postini 更经济、更省时。YMMV。

相关内容