Newsgroup: it.comp.os.linux.sys
Titolo: Postfix & hash

ciao a tutti,
ci sono dei "limiti" sul numero di record "inseribili"
in una mappa hash per postfix?
Ad esempio, posso inserire valori prossimi a milioni di record
o in tal caso sarebbe meglio puntare ad altri database o
splittare le mappe su più file?
Parlo esclusivamente in termini di performance durante il lookup
di postfix e non in termini pratico-logistici della gestione da
parte mia.

 postfix e non in termini pratico-logistici della gestione da parte mia.
Teoricamente le hash map sono pensate per rispondere alle richieste in 
tempo O(1).
Non so su che cifre siano tarate quelle di postfix, ma penso che qualche 
milione di record li reggano senza problemi.
Penso che il limite piu` grosso sia la dimensione del file: se ci sta 
tutto in RAM non dovresti avere problemi. Se deve andare spesso sul disco 
quello sarebbe il collo di bottiglia.
Non credo che passare ad altri tipi di storage convenga particolarmente, 
perche` usano algoritmi generici di hashing e indicizzazione, e non 
ottimizzati per i dati che postfix deve trattare, e perche` aggiungi 
comunque un overhead per la connessione e l'interrogazione (sto pensando a 
motori SQL o simili).
Bye.

 in una mappa hash per postfix?
Boh. Però il mio hash più grosso ha circa 25K entry.
Non so cosa diamine devi farci tu, ma a me ancora non è esploso nulla...
-- 
http://bofhskull.wordpress.com/

 Non so cosa diamine devi farci tu, ma a me ancora non è esploso nulla...
Giusto per sapere, avendo tutto su MySQL potrei accorpare determiante
tabelle in un singolo hash (con OK/REJECT) e dopo aver impostato tutto
non vorrei ritrovarmi nella buffa situazione di aver raggiunto i limiti
del database o di postfix. Meglio saperlo prima....

 motori SQL o simili).
Ok, overhead a parte (che penso sia trascurabile su macchine attuale a
meno che non si abbiamo milioni di qps) un database mysql di due colonne
(tanto per dirne una) ti regge tranquillamente svariati milioni e
milioni di record rispondendo sempre con valori prossimi a 0.02ms

 milioni di record rispondendo sempre con valori prossimi a 0.02ms
L'overhead lo devi considerare se postfix apre e chiude le connessioni 
continuamente. Ma se le tiene aperte puoi ignorarlo quasi del tutto, anche 
perche` penso che precompili le query rendendole parametriche, quindi non 
perdi nemmeno quel tempo.
Ma appunto, gli algoritmi di hashing credo siano simili. Magari quello di 
MySQL e` pensato per miliardi di valori (un hash a 32 bit basta per 4 
miliardi di entry), ma penso che anche quello di postfix usi almeno 32bit, 
per questo dicevo che per milioni di entry non dovresti vedere la 
differenza.
Forse quello di postfix e` piu` adatto a gestire indirizzi email, quindi 
con componenti simili (il dominio), e li distribuisce meglio nel file di 
hash, mentre quello di MySQL e` piu` generico e non tiene conto di queste 
finezze. Ma sono solo ipotesi mie, non ho guardato i sorgenti.
In ogni caso penso che la differenza di prestazioni possa essere tra lo 0 
e il 15%, volendo buttare li` una cifra.
Bye.

 e il 15%, volendo buttare li` una cifra.
Diciamo pure che tutto il discorso precedente, per quanto voglia apparire
tecnico, lascia molto a desiderare.
Se poi ci butti di mezzo anche i numeri, diciamo che si sfiora il ridicolo.
-- 
A: Because we read from top to bottom, left to right.
Q: Why should i start my reply below the quoted text?

 ridicolo.
Attendo una spiegazione tecnica dettagliata, allora.

 perdi nemmeno quel tempo.
Pensi sbagliato.


 Pensi sbagliato.
Amen.
Vuol dire che c'e` spazio per l'ottimizzazione.

 o dati concreti.
No ho offeso. Lungi da me.
Ma ti ricordo che siamo su icol.sys, non su
- it.comp.os.linux.filosofia.
Se uno deve parlare, che lo faccia a ragion veduta, non "un tanto al
chilo", sparando a caso o ipotizzando malamente (giustificandosi poi che
c'è spazio per le ottimizzazioni).
Max
P.S.: se vogliamo fare la punta al pene, spiegami pure dove hai letto che
multithread vs multiprocess è identico a livello prestazionale
(possibilmente senza mischiare cavoli e pere, anche perchè ciò che dici
dipende tantissimo da cosa bisogna implementare). 


 dipende tantissimo da cosa bisogna implementare).
Non ho mai detto che e` identico. Ho detto che sotto Linux c'e` poca 
differenza, perche` la creazione di processi e` ottimizzata quasi quanto 
quella dei thread.
Nel caso specifico, i processi da una parte vengono comunque creati 
(postfix crea un processo per ogni mail che entra nella sua coda, che usi 
gli hash o mysql), mentre i thread di Mysql o sono gia` presenti o vengono 
creati al volo, ma rappresentano comunque un overhead rispetto al solo 
postfix.
Inoltre, una volta che un file e` aperto in lettura, la sua memoria viene 
condivisa tra i processi che lo usano. La stessa cosa avviene per i 
thread. Quindi anche qui non c'e` praticamente differenza nella velocita` 
di accesso.
La mia ipotesi e` che in ogni caso MySQL possa essere piu` lento delle 
hash di postfix, perche` c'e` sempre un overhead, per quanto piccolo.
Overhead che, ragionevolmente e probabilmente, sara` sempre superiore a 
qualsiasi differenza di implementazione della funzione di hashing e al 
conseguente accesso al dato.
Anche solo passare per un socket, per quanto Unix, per l'interpretazione 
della query, per la concorrenza di accesso di altri software al database, 
ecc.
Questo nello scenario ottimale che i dati stiano comunque in RAM.
Se cambia lo scenario e ci sono varianti (uno ha RAM, l'altro no, uno ha 1 
milione di record, l'altro 10.000, uno ha una CPU a 4 GHz, l'altro a 300 
MHz) non si possono fare ipotesi, ma non mi sembra questo il caso.

 quella dei thread.
tu vuoi scatenare una guerra vero ? :)

 MHz) non si possono fare ipotesi, ma non mi sembra questo il caso.
Almeno, adesso, non hai sparato numeri campati in aria.


 non sia "hello world" in C ?
Vedi sopra.
 

 diverso).
qua non ti seguo
 

 due processi, ma che fanno riferimento alla stessa area di memoria fisica.
non viene mappato (i file memory mapped esistono ma sono un'altra cosa).
fopen/fread non mappano nulla.
Semplicemente il kernel riempie i buffer indicati ed allocati dal programma
con i dati che ha, eventualmente, in cache.
Dal punto di vista dei programmi NON fanno riferimento alla stessa memoria.




vedasi man exec, man execve e man fork
The  exec()  family  of  functions  replaces  the current process image
with a new process image.  The functions
described in this manual page are front-ends for the function execve(2).
(See the manual page for execve()  for
detailed information about the replacement of the current process.)
execve()  executes the program pointed to by filename.  filename must be
either a binary executable, or a script
starting with a line of the form "#! interpreter [arg]".  [CUT]
execve() does not return on success, and the text, data, bss, and stack of
the calling process  are  overwritten
by  that  of  the  program  loaded.   The  program invoked inherits the
calling process’s PID, and any open file
descriptors that are not set to close-on-exec.
fork()  creates  a  child process that differs from the parent process only
in its PID and PPID, and in the fact
that resource utilizations are set to 0.  File locks and pending signals
are not inherited.
Under Linux, fork() is implemented using copy-on-write pages, so the only
penalty that it incurs is the time and
memory required to duplicate the parent’s page tables, and to create a
unique task structure for the child.
----------
per farla breve e molto semplice, quando da bash lanci "/bin/ls", esegui un
exec.
Un fork invece "duplica" il tuo programma, tutto compreso e continua ad
eseguirlo da dopo la chiamata. Se il programma che forka utilizza 1G di
memoria, dopo il fork avrai 2 programmi che utilizzano 2G.
Nota a latere: esistono delle tecniche che permettevano, su kernels vecchi,
di fare dei "fork bombing" che esaurivano le risorse del sistema e facevano
chiantare la macchina (quindi non è una operazione tanto leggera).


 leggera).
Esistono ancora. Basta fare fork di continuo cambiando una variabile 
nell'heap e non aver messo limiti con ulimit. Ma anche solo forkando, 
prima o poi si satura la lista dei processi e altre strutture del kernel.
Coi thread cambia solo il numero di thread e il tempo che impiega, ma il 
risultato e` simile.
A meno che non abbiano introdotto di recente dei limiti a livello kernel.
Bye.

 exec.
Se si esegue una exec senza forkare, il programma che l'ha eseguita
muore.
(com'era la storia dell' hello world in C ?)
#include <stdio.h>
#include <unistd.h>
int main()
{
 execl("/bin/ls", "/bin/ls",  NULL);
 printf("Can you read me, CtRix?\n");
}
 

 (com'era la storia dell' hello world in C ?)
Si vabbè era per farla semplice eh...
:-D
