Domanda

Un prodotto su cui sto lavorando raccoglie diverse migliaia di letture al giorno e le memorizza come file binari 64k su una partizione NTFS (Windows XP). Dopo un anno di produzione ci sono oltre 300000 file in una singola directory e il numero continua a crescere. Ciò ha reso molto dispendioso l'accesso alle directory padre / antenato da Windows Explorer.

Ho provato a disattivare il servizio di indicizzazione ma questo non ha fatto differenza. Ho anche pensato di spostare il contenuto del file in un database / file zip / tarball ma è vantaggioso per noi accedere ai file individualmente; in sostanza, i file sono ancora necessari per scopi di ricerca e i ricercatori non sono disposti a occuparsi di nient'altro.

C'è un modo per ottimizzare NTFS o Windows in modo che possa funzionare con tutti questi piccoli file?

È stato utile?

Soluzione

Le prestazioni NTFS peggiorano notevolmente dopo 10.000 file in una directory. Quello che fai è creare un livello aggiuntivo nella gerarchia di directory, con ogni sottodirectory con 10.000 file.

Per quello che vale, questo è l'approccio adottato dalla gente SVN in versione 1.5 . Hanno usato 1.000 file come soglia predefinita.

Altri suggerimenti

NTFS in realtà funzionerà benissimo con molti più di 10.000 file in una directory purché tu gli dica di smettere di creare nomi di file alternativi compatibili con piattaforme Windows a 16 bit. Per impostazione predefinita, NTFS crea automaticamente un nome di file "8 punti 3" per ogni file creato. Questo diventa un problema quando ci sono molti file in una directory perché Windows guarda i file nella directory per assicurarsi che il nome che stanno creando non sia già in uso. È possibile disabilitare la denominazione "8 punti 3" impostando il valore del Registro di sistema NtfsDisable8dot3NameCreation su 1. Il valore si trova nel percorso del registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ FileSystem. È sicuro apportare questa modifica poiché i file di nome "8 dot 3" sono richiesti solo dai programmi scritti per versioni molto vecchie di Windows.

È necessario riavviare prima che questa impostazione abbia effetto.

Il problema delle prestazioni è causato dall'enorme quantità di file in una singola directory: una volta eliminato, dovresti andare bene. Questo non è un problema specifico di NTFS: in effetti, si incontra comunemente con i file home / mail dell'utente su grandi sistemi UNIX.

Un modo ovvio per risolvere questo problema è spostare i file in cartelle con un nome basato sul nome del file. Supponendo che tutti i tuoi file abbiano nomi di file di lunghezza simile, ad es. ABCDEFGHI.db, ABCEFGHIJ.db, ecc., Creano una struttura di directory come questa:

ABC\
    DEF\
        ABCDEFGHI.db
    EFG\
        ABCEFGHIJ.db

Utilizzando questa struttura, è possibile individuare rapidamente un file in base al suo nome. Se i nomi dei file hanno una lunghezza variabile, scegli una lunghezza massima e anteporre zero (o qualsiasi altro carattere) per determinare la directory di appartenenza del file.

Ho visto enormi miglioramenti in passato dalla suddivisione dei file in una gerarchia di directory nidificata per, ad esempio, prima e poi seconda lettera del nome file; quindi ogni directory non contiene un numero eccessivo di file. La manipolazione dell'intero database è comunque lenta.

Potresti provare a usare qualcosa come Solid File System.

Questo ti dà un file system virtuale che le applicazioni possono montare come se fosse un disco fisico. La tua applicazione vede molti piccoli file, ma solo un file si trova sul tuo disco rigido.

http://www.eldos.com/solfsdrv/

Se riesci a calcolare i nomi dei file, potresti essere in grado di ordinarli in cartelle per data, in modo che ogni cartella abbia solo file per una data particolare. Potresti anche voler creare gerarchie di mesi e anni.

Inoltre, potresti spostare i file più vecchi di un anno in una posizione diversa (ma ancora accessibile)?

Infine, e ancora una volta, questo richiede che tu sia in grado di calcolare i nomi, scoprirai che l'accesso diretto a un file è molto più veloce rispetto al tentativo di aprirlo tramite Explorer. Ad esempio, dicendo
notepad.exe " P: \ ath \ to \ your \ filen.ame "
dalla riga di comando dovrebbe effettivamente essere piuttosto rapido, supponendo che tu conosca il percorso del file che ti serve senza dover ottenere un elenco di directory.

Un trucco comune è semplicemente creare una manciata di sottodirectory e dividere i file.

Ad esempio, Doxygen, un programma di documentazione del codice automatizzato che può produrre tonnellate di pagine html, ha un'opzione per creare una gerarchia di directory profonde a due livelli. I file vengono quindi distribuiti uniformemente nelle directory inferiori.

Avere centinaia di migliaia di file in una singola directory paralizzerà davvero NTFS, e non c'è molto da fare al riguardo. Dovresti riconsiderare la memorizzazione dei dati in un formato più pratico, come un grande tarball o in un database.

Se hai davvero bisogno di un file separato per ogni lettura, dovresti ordinarli in più sottodirectory invece di averli tutti nella stessa directory. Puoi farlo creando una gerarchia di directory e inserendo i file in file diversi a seconda del nome del file. In questo modo è ancora possibile archiviare e caricare i file conoscendo solo il nome del file.

Il metodo che usiamo è quello di prendere le ultime lettere del nome del file, invertirle e creare directory di una lettera da quella. Ad esempio, considerare i seguenti file:

1.xml
24.xml
12331.xml
2304252.xml

puoi ordinarli in directory in questo modo:

data/1.xml
data/24.xml
data/1/3/3/12331.xml
data/2/5/2/4/0/2304252.xml

Questo schema garantirà che non avrai mai più di 100 file in ogni directory.

Ho riscontrato questo problema molte volte in passato. Abbiamo provato ad archiviare per data, comprimendo i file sotto la data in modo da non avere molti piccoli file, ecc. Tutti erano bandaidi al vero problema di archiviare i dati come molti piccoli file su NTFS.

Puoi andare su ZFS o su qualche altro file system che gestisce meglio i file di piccole dimensioni, ma fermati e chiedi se è NECESSARIO archiviare i file di piccole dimensioni.

Nel nostro caso alla fine siamo passati a un sistema in cui tutti i piccoli file per una certa data sono stati aggiunti in un modo TAR con semplici delimitatori per analizzarli. I file del disco sono passati da 1,2 milioni a meno di qualche migliaio. In realtà si sono caricati più velocemente perché NTFS non è in grado di gestire molto bene i file di piccole dimensioni e l'unità è stata comunque in grado di memorizzare nella cache un file da 1 MB. Nel nostro caso il tempo di accesso e analisi per trovare la parte giusta del file era minimo rispetto all'effettiva memorizzazione e manutenzione dei file archiviati.

Oltre a posizionare i file nelle sottodirectory ..

Personalmente, svilupperei un'applicazione che mantiene la stessa interfaccia per quella cartella, cioè tutti i file vengono visualizzati come singoli file. Quindi, in background dell'applicazione effettivamente prende questi file e li combina in file più grandi (e poiché le dimensioni sono sempre 64k, ottenere i dati di cui hai bisogno dovrebbe essere relativamente facile) Per sbarazzarti del disordine che hai.

In questo modo puoi ancora facilitare l'accesso ai file desiderati, ma ti consente anche di avere un maggiore controllo sulla struttura di tutto.

Considerare di trasferirli su un altro server che utilizza un filesystem più adatto a enormi quantità di piccoli file (ad esempio Solaris con ZFS)?

Se ci sono aspetti significativi, categorici, dei dati, è possibile annidarli in un albero di directory. Credo che il rallentamento sia dovuto al numero di file in una directory, non al semplice numero di file stessi.

Il raggruppamento generale più ovvio è per data e offre una struttura di annidamento a tre livelli (anno, mese, giorno) con un limite relativamente sicuro sul numero di file in ciascuna directory foglia (1-3k).

Anche se sei in grado di migliorare le prestazioni del filesystem / browser dei file, sembra che questo sia un problema che ti imbatterai in altri 2 o 3 anni ... solo guardando un elenco di 0,3-1mil file è incorrerà in un costo, quindi potrebbe essere meglio a lungo termine trovare modi per esaminare solo sottoinsiemi più piccoli dei file.

L'uso di strumenti come 'trova' (sotto cygwin o mingw) può rendere la presenza dell'albero della sottodirectory un problema durante la navigazione dei file.

Rinomina la cartella ogni giorno con un timestamp.

Se l'applicazione sta salvando i file in c: \ Readings, imposta un'attività pianificata per rinominare Reading a mezzanotte e creare una nuova cartella vuota.

Quindi otterrai una cartella per ogni giorno, ognuno contenente diverse migliaia di file.

Puoi estendere ulteriormente il metodo al raggruppamento per mese. Ad esempio, C: \ Reading diventa c: \ Archive \ September \ 22.

Devi stare attento con i tuoi tempi per assicurarti di non provare a rinominare la cartella mentre il prodotto ci sta salvando.

Per creare una struttura di cartelle che si ridimensionerà su un grande numero sconosciuto di file, mi piace il seguente sistema:

Dividi il nome del file in pezzi di lunghezza fissa, quindi crea cartelle nidificate per ogni pezzo tranne l'ultimo.

Il vantaggio di questo sistema è che la profondità della struttura delle cartelle aumenta solo quanto la lunghezza del nome file. Quindi, se i tuoi file vengono generati automaticamente in una sequenza numerica, la struttura è solo profonda è deve essere.

12.jpg -> 12.jpg
123.jpg -> 12\123.jpg
123456.jpg -> 12\34\123456.jpg

Questo approccio significa che le cartelle contengono file e sottocartelle, ma penso che sia un ragionevole compromesso.

Ed ecco un bellissimo PowerShell one-liner per iniziare!

$s = '123456'

-join  (( $s -replace '(..)(?!$)', '$1\' -replace '[^\\]*,'' ), $s )
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top