Come ridurre al minimo l'uso della memoria di SpamAssassin (spamd)


15

Sto usando SpamAssassin su Debian (la configurazione predefinita con Pyzor, AWL e Bayes disabilitati e sa-compile abilitata), e ciascuno dei processi figlio spamd consuma da 100 a 150 MB di memoria (circa 50 MB di memoria reale) sul 32 server bit e circa il doppio (abbastanza logicamente) sui server a 64 bit. Esistono generalmente due processi figlio, ma nei momenti di punta possono esserci cinque (il massimo) in esecuzione.

ISTM che da 200 a 600 MB è un sacco di memoria per questo compito. Vorrei continuare a utilizzare SA come parte della mia struttura di filtro, ma sta diventando difficile giustificare tanta memoria.

Esistono modi per ridurre la quantità di memoria utilizzata da ogni processo figlio? (O in alternativa, fai un processo figlio singolo così veloce che posso impostare il numero massimo di figli su qualcosa come 2?). Sono disposto a prendere in considerazione qualsiasi opzione, comprese quelle che possono o possono comportare una precisione ridotta.

Ho già letto la pagina "Problemi di memoria esaurita" sul wiki SA ; nulla di utile. I messaggi di dimensioni superiori a 5 MB non vengono sottoposti a scansione con SA.


1
Si noti che i bambini biforcati possono usare molta meno RAM fisica rispetto alla somma dei numeri ps o top show. Ciò è dovuto alla strategia di copia su scrittura durante il fork.
David Schmitt,

Risposte:


5

Penso che tu abbia frainteso il modo in cui Linux segnala l'utilizzo della memoria. Quando un processo esegue il fork, si ottiene un secondo processo che condivide molte risorse con il processo originale. Incluso in questo è la memoria. Tuttavia, Linux utilizza una tecnica nota come Copy On Write (COW) per questo. Ciò significa che ogni processo figlio biforcuto vedrà gli stessi dati in memoria del processo originale, ma ogni volta che tali dati cambiano (dal figlio o dal genitore), le modifiche vengono copiate e solo allora puntano a una nuova posizione.

Fino a quando uno dei processi non modifica tali dati, condividono la stessa copia. Di conseguenza, potrei avere un processo che utilizza 100 MB di RAM e fork 10 volte. Ognuno di quei processi biforcati mostrerebbe 100 MB di RAM in uso, ma se si guardasse l'utilizzo complessivo della memoria sulla scatola, potrebbe solo mostrare che vengono utilizzati 130 MB di RAM (100 MB condivisi tra i processi, oltre a qualche MB di overhead , più un'altra dozzina di MB o due per il resto del sistema).

Come ultimo esempio, ho una scatola in questo momento con 30 processi Apache in esecuzione. Ogni processo mostra un utilizzo di 22 MB di RAM. Tuttavia, quando eseguo free -m per mostrare il mio utilizzo complessivo di RAM, ottengo:

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

Come puoi vedere, questa scatola non ha nemmeno abbastanza RAM per eseguire 30 processi che utilizzavano ciascuno 18 MB di RAM "reale". A meno che tu non stia letteralmente esaurendo la RAM o le tue app si scambino pesantemente, non mi preoccuperei delle cose.

AGGIORNAMENTO: controlla anche questo strumento chiamato smem , menzionato da jldugger nella risposta a un'altra domanda sull'utilizzo della memoria Linux qui .


1
Sto letteralmente esaurendo la RAM, quindi devo preoccuparmene. Tuttavia, potrebbe essere che altri processi stiano consumando la RAM e SA non stia usando così tanto.
Tony Meyer,

Dalla mia osservazione e dall'utilizzo dello strumento smem , sembra che lo spamassassin utilizzi circa 50 MB di RAM e che se lo installi in più processi, quasi tutta la loro memoria è memoria condivisa, quindi utilizzerà comunque circa 50 MB di RAM in totale tra tutti i processi, anche se ps riporta ognuno con un RSS di 50 MB. YMMV.
thomasrutter,

1

Usando sa-compile potresti essere in grado di migliorare la velocità di abbinamento di molte regole.


Scusa, avrei dovuto menzionare nella domanda che sto già usando sa-compile. Un buon suggerimento, comunque.
Tony Meyer,

1

Ecco cosa ho fatto.

Ho un set-up in cui molti messaggi tendono a essere consegnati all'incirca allo stesso tempo; per una serie di esperimenti eseguo SA su messaggi che vengono copiati in uno spool temporaneo e poi consegnati da un cron job ogni cinque minuti.

spamd continuerei a stampare "forse dovresti aumentare il parametro max-children" e l'ho alzato fino a 40 in un punto, ma ho avuto il server che consumava tutto il suo spazio di swap e si bloccava.

Ora ho implementato un regime diverso in cui la consegna è regolata da un file di blocco Procmail. Poiché era semplice da fare, utilizzo solo l'ultima cifra dell'ID processo ed eseguo con 10 figli. Non sono affatto sicuro che sia ottimale, ma ha già aiutato a evitare i picchi di carico folli che di tanto in tanto travolsi dall'esperienza.

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

Inoltre, avvio spamdcon una serie di ulimitrestrizioni. I numeri sono stati estratti da http://svn.apache.org/repos/asf/spamassassin/trunk/contrib/run-masses, tranne per il fatto che ho rimosso la ulimit -urestrizione. (Non sono sicuro di quello che sta succedendo. 32 è troppo piccolo in ogni caso. Con qualcosa come 500 potrei continuare a spamdcorrere per un po ', ma alla fine corro nel limite.)

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

Immagino che finirò con errori di consegna se il carico è troppo elevato per un tempo prolungato, ma finora sembra che sia riuscito a ridurre il carico a livelli gestibili con questo; e un sacco di consegne fallite è ancora molto meglio della macchina che si sta esaurendo lo scambio.


0

Le medie di carico elevato sono (a volte) un sintomo indiretto che la macchina sta esaurendo la RAM (e utilizzando molti processi di scambio CPU avanti e indietro dalla memoria virtuale), quindi potresti provare a configurare il tuo server di posta per non passare la posta attraverso SpamAssassin se il le medie di carico sono troppo alte.

Non dici quale MTA stai eseguendo, ma se chiami SA da un elenco di controllo di accesso in exim4, il suggerimento in fondo a questo messaggio è efficace.

Inoltre, puoi alleggerire il carico su SA e quindi ridurne l'utilizzo della memoria, mettendo davanti ad esso alcuni altri metodi di filtraggio dello spam, meno dispendiosi in termini di risorse (ad esempio, quindi elaborano e rifiutano lo spam prima che arrivi a SA) - ad esempio, greylisting e mittente verificano che i callout utilizzino relativamente poca RAM.


Su una nota correlata, sto seriamente prendendo in considerazione la possibilità di abbandonare SA a favore di dspam su un paio di server che eseguo, poiché dspam è presumibilmente meno affamato di RAM.
David North,

Come via di mezzo, potresti eseguire un filtro bayesiano come primo passo e tornare a SpamAssassin solo per i messaggi per i quali il primo filtro non ha emesso un chiaro verdetto. Gli spammer tendono a ripetersi molto, quindi probabilmente potresti gestire la stragrande maggioranza dei casi senza SpamAssassin, ma hai ancora a disposizione per nuovi focolai ecc.
Tripleee,

0

Eravamo in una situazione simile diversi mesi fa. SpamAssassin e ClamAV utilizzavano molta memoria su un server ospitato. Avevamo la possibilità di aggiungere più memoria al server, ma si è rivelato più conveniente ed economico passare a Postini. YMMV.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.