如何最小化SpamAssassin(spamd)内存使用


15

我在Debian上使用SpamAssassin(默认配置中禁用了Pyzor,AWL和Bayes,并启用了sa-compile),并且每个spamd子进程在32位上占用了大约100到150MB的内存(大约50MB的实际内存)位服务器,大约是64位服务器上的两倍(在逻辑上足够)。通常有两个子进程,但是在繁忙时间可以运行五个(最大)。

在200至600MB的ISTM中,此任务需要大量内存。我想继续将SA用作我的过滤结构的一部分,但是要证明如此大的内存正变得越来越困难。

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

我已经阅读了SA Wiki上的“内存不足问题”页面;没有任何用处。SA不会扫描大于5 MB的邮件。


1
请注意,分叉的孩子使用的物理RAM可能比ps或top show的数字之和少得多。这是由于分叉时的写时复制策略。
David Schmitt,2009年

Answers:


5

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

在其中一个流程对数据进行更改之前,它们将共享同一副本。结果,我可以拥有一个使用100MB RAM的进程,并将其派生10次。每个分叉的进程将显示100MB的RAM正在使用,但是如果您查看包装盒上的总体内存使用情况,则可能仅显示130MB的RAM正在使用(进程之间共享100MB,再加上几MB的开销,以及系统其余部分的另外一十二MB)。

作为最后一个示例,我现在有一个正在运行30个apache进程的框。每个进程都显示22MB RAM的使用。但是,当我运行free -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或应用程序正在大量交换,否则我不会担心任何事情。

更新:另外,请签出jldugger提到的这个名为smem的工具,此处回答了另一个有关Linux内存使用的问题


1
我实际上已经用完了RAM,所以我确实需要为此担心。但是,可能是其他进程正在消耗RAM,而SA并没有使用太多内存。
托尼·迈尔

从我的观察和使用工具smem来看,spamassassin似乎使用大约50 MB的RAM,并且如果将其分叉到多个进程中,几乎它们的所有内存都是共享内存,因此它仍将使用大约50 MB的RAM在所有进程中,即使ps报告每个进程都具有50 MB的RSS。YMMV。
thomasrutter 2012年


1

这就是我所做的。

我有一个设置,其中往往趋向于同时发送许多消息;为了进行一系列实验,我对复制到临时假脱机然后由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

我想如果负载过长的时间过长会导致交付失败,但是到目前为止,看来我已经设法将负载降低到可管理的水平。而且一堆失败的交付仍然比交换用完的机器好得多。


0

高负载平均是(有时)计算机出现RAM不足(并且使用大量虚拟内存来回往返CPU交换进程)的间接症状,因此,如果平均负载过高。

您没有提到您正在运行哪个MTA,但是如果您要从exim4的访问控制列表中调用SA,则此消息底部的建议将有效。

另外,您可以通过在SA前面放置其他一些资源占用较少的垃圾邮件过滤方法来减轻SA的负担,从而减少其内存使用量(即,它们在到达SA之前会处理并拒绝一些垃圾邮件)-例如,灰名单和发件人验证标注使用的RAM相对较少。


与此相关的是,我正在认真考虑放弃SA,而在我运行的几个服务器上放弃dspam,因为据称dspam占用的内存更少。
David North

作为中间立场,您可以首先运行贝叶斯过滤器,然后仅针对第一个过滤器没有明确判定的消息退回到SpamAssassin。垃圾邮件发送者往往会重复自己很多,所以你很可能应付绝大多数没有SpamAssassin的情况下,但仍然有它可用于新疫情等
tripleee

0

几个月前,我们处于类似情况。SpamAssassin和ClamAV在托管服务器上使用了大量内存。我们可以选择向服务器添加更多内存,但是事实证明,切换到Postini更具成本效益和时间效率。YMMV。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.