2013-07-18 12 views
8

In un sistema Solaris che elabora un numero elevato di file e memorizza le loro informazioni in un database (sì, so che l'utilizzo del database è il modo più veloce per ottenere informazioni sul numero di file che abbiamo). Ho bisogno di un modo rapido per monitorare i file mentre procedono attraverso il sistema nel loro percorso verso l'archiviazione in un database.il modo più veloce per contare il numero di file in una directory contenente centinaia di migliaia di file

Attualmente utilizzo uno script perl che legge nella directory in un array e quindi acquisisce la dimensione dell'array e lo invia a uno script di monitoraggio. Sfortunatamente mentre il nostro sistema cresce, questo monitor sta diventando sempre più lento.

Sto cercando un metodo che funzioni molto più rapidamente invece di mettere in pausa e aggiornare ogni 15-20 secondi dopo aver eseguito l'operazione di conteggio su tutte le directory interessate.

Sono relativamente certo che il mio collo di bottiglia è la directory di lettura nell'operazione di array.

Non ho bisogno di informazioni sui file, non ho bisogno di dimensioni o nomi di file, solo il numero di file nella directory.

Nel mio codice non conto i file nascosti oi file di testo che utilizzo per conservare le informazioni di configurazione. Sarebbe bello se questa funzionalità fosse preservata ma non è certamente obbligatoria.

Ho trovato alcuni riferimenti al conteggio degli inode con codice C o qualcosa del genere, ma non sono molto esperto in quell'area.

Mi piacerebbe rendere questo monitor il più possibile in tempo reale.

Il codice perl che uso si presenta così:

opendir (DIR, $currentDir) or die "Cannot open directory: $!"; 
@files = grep ! m/^\./ && ! /config_file/, readdir DIR; # skip hidden files and config files 
closedir(DIR); 
$count = @files; 
+0

discussioni utilizzo Perl o forchette per ridurre al minimo il tempo di attesa –

+0

@mpapec Mi piace l'idea, nel migliore dei casi questo sarebbe ancora fare il mio tempo di attesa vicino alla quantità di tempo che ci sarebbe se ho eseguito questo codice solo sulla mia directory più lunga? Se è così, non è una cattiva idea, ma sfortunatamente la maggior parte delle mie directory ha meno di 50 file mentre uno o due ne hanno migliaia. Mi piacerebbe trovare un modo per evitare di leggere tutti i file nella directory. – Andrew

risposta

9

Quello che fai in questo momento si legge l'intera directory (più o meno) in memoria solo per scartare che il contenuto per il suo conteggio. Evitare che in streaming la directory invece:

my $count; 
opendir(my $dh, $curDir) or die "opendir($curdir): $!"; 
while (my $de = readdir($dh)) { 
    next if $de =~ /^\./ or $de =~ /config_file/; 
    $count++; 
} 
closedir($dh); 

È importante sottolineare che, non utilizzare glob() in una qualsiasi delle sue forme. glob() will expensively stat() every entry, che è non overhead che si desidera.

Ora, potresti avere modi molto più sofisticati e più leggeri di fare ciò a seconda delle funzionalità del sistema operativo o delle funzionalità del filesystem (Linux, a titolo di confronto, offre inotify), ma lo streaming della directory come sopra vale quanto tu Prenderò portabilmente.

+0

Mi piace. Penso che tu abbia ragione. Voglio stare lontano dalle soluzioni specifiche del file system per ora. Potrei seguire questa strada in futuro, ma voglio mantenere questa cosa il più portabile possibile. Grazie! Questo ha accelerato un po 'le cose. Non è MOLTO più veloce ma aiuta. – Andrew

-1

Cortocircuito.

@files = readdir(DIR) - 2; 

The -2 is because readdir counts "." and ".." as directory entries. 

print @files . " files found\n"; 
exit; 

1 file trovati

+0

L'ipotesi che ci siano esattamente 2 dotfile in qualsiasi directory è un'assunzione estremamente pericolosa e molto spesso errata. inoltre la domanda posta per consentire l'esclusione di specifici file di configurazione. infine questo suggerimento non è più veloce del precedente in quanto il collo di bottiglia è l'operazione di lettura che esiste nella soluzione di cui sopra. – Andrew

+0

-1 Un po 'problematico. 'readdir' in un contesto scalare restituisce la successiva voce di directory, piuttosto che il numero di voci (rimanenti?). Quindi stai sottraendo due da questo nome file, che è probabilmente convertito in valore numerico zero. Stai quindi assegnando lo scalare -2 a un elenco. E come osservato da @Andrew, l'OP deve comunque escludere tutti i dotfile e altri modelli specifici. – pilcrow

Problemi correlati