Я использую SpamAssassin в Debian (конфигурация по умолчанию с отключенными Pyzor, AWL и Bayes и включенным sa-compile), и каждый из дочерних процессов spamd потребляет от 100 до 150 МБ памяти (около 50 МБ реальной памяти) на 32 битовые серверы и примерно вдвое больше (логично) на 64-битных серверах. Обычно есть два дочерних процесса, но в периоды наибольшей нагрузки их может быть пять (максимум).
ISTM, что от 200 до 600 МБ памяти - это много для этой задачи. Я хотел бы продолжать использовать SA как часть моей структуры фильтрации, но становится трудно оправдать такой объем памяти.
Есть ли способы уменьшить объем памяти, который использует каждый дочерний процесс? (Или, альтернативно, сделать один дочерний процесс настолько быстрым, чтобы я мог установить максимальное количество дочерних процессов примерно на 2?). Я готов рассмотреть любые варианты, в том числе те, которые приведут или могут привести к снижению точности.
Я уже читал Страница "Проблемы с нехваткой памяти" в вики-сайте SA; ничего там бесполезно. Сообщения размером более 5 МБ не сканируются с помощью SA.
Я думаю, вы неправильно понимаете, как Linux сообщает об использовании памяти. Когда процесс разветвляется, это приводит к появлению второго процесса, который разделяет много ресурсов с исходным процессом. В том числе и память. Однако в Linux для этого используется метод, известный как Копирование при записи (COW). Это означает, что каждый разветвленный дочерний процесс будет видеть в памяти те же данные, что и исходный процесс, но всякий раз, когда эти данные изменяются (дочерним или родительским), изменения копируются и только затем указывают на новое место.
Пока один из процессов не внесет изменения в эти данные, они будут использовать одну и ту же копию. В результате я мог бы получить процесс, использующий 100 МБ ОЗУ, и выполнить его 10 разветвлений. Каждый из этих разветвленных процессов будет показывать использование 100 МБ ОЗУ, но если вы посмотрите на общее использование памяти на коробке, это может показать только то, что используется 130 МБ ОЗУ (100 МБ совместно используются процессами, плюс несколько МБ накладных расходов. , плюс еще десяток-другой МБ для остальной системы).
В качестве последнего примера у меня сейчас есть ящик с 30 запущенными процессами apache. Каждый процесс показывает использование 22 МБ ОЗУ. Однако когда я бегу бесплатно -m чтобы показать общее использование ОЗУ, я получаю:
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
Как видите, в этом блоке даже не хватает ОЗУ для запуска 30 процессов, каждый из которых использует 18 МБ «реальной» ОЗУ. Если у вас буквально не заканчивается ОЗУ или ваши приложения сильно не меняются местами, я бы не стал беспокоиться о вещах.
ОБНОВЛЕНИЕ: также проверьте этот инструмент под названием смем, упомянутый бродяга в ответе на другой вопрос об использовании памяти Linux Вот.
Вот что я сделал.
У меня есть система, в которой много сообщений доставляется примерно в одно и то же время; Для серии экспериментов я запускаю SA для сообщений, которые копируются во временную спул и затем доставляются заданием cron каждые пять минут.
spamd
продолжал печатать «возможно, вам следует увеличить параметр max-children», и в какой-то момент я поднял его до 40, но у меня был сервер, потребляющий все свое пространство подкачки и вылетавший.
Теперь я реализовал другой режим, в котором доставка регулируется файлом блокировки Procmail. Поскольку это было просто сделать, я просто использую последнюю цифру идентификатора процесса и запускаю с 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
Я предполагаю, что в конечном итоге у меня будут сбои в доставке, если нагрузка будет слишком высокой в течение длительного времени, но пока мне кажется, что с помощью этого мне удалось снизить нагрузку до приемлемого уровня; и куча неудавшихся доставок по-прежнему намного лучше, чем у машины, у которой заканчивается своп.
С помощью sa-compile вы можете улучшить скорость сопоставления многих правил.
Средние высокие показатели нагрузки (иногда) являются косвенным признаком того, что на вашем компьютере заканчивается ОЗУ (и используется много процессов перестановки ЦП из виртуальной памяти), поэтому вы можете попробовать настроить свой почтовый сервер так, чтобы он не передавал почту через SpamAssassin, если средние нагрузки слишком высоки.
Вы не упоминаете, какой MTA вы используете, но если вы вызываете SA из списка управления доступом в exim4, тогда предложение внизу это сообщение эффективен.
Кроме того, вы можете уменьшить нагрузку на SA и, таким образом, уменьшить его использование памяти, поставив перед ним некоторые другие, менее ресурсоемкие методы фильтрации спама (т.е. чтобы они обрабатывали и отклоняли некоторый спам до того, как он попадет в SA) - например, вызовы «серые списки» и «проверка отправителя» используют относительно мало оперативной памяти.
Несколько месяцев назад мы были в похожей ситуации. SpamAssassin и ClamAV использовали много памяти на размещенном сервере. У нас была возможность увеличить объем памяти на сервере, но оказалось, что переход на Postini оказался более экономичным с точки зрения затрат и времени. YMMV.