2009-11-07 14 views
6

Ho circa 750.000.000 di file che ho bisogno di archiviare su disco. Inoltre, ho bisogno di poter accedere a questi file in modo casuale - qualsiasi file dato in qualsiasi momento - nel più breve tempo possibile. Cosa devo fare per rendere più rapido l'accesso a questi file?Accesso/archiviazione file più veloce?

Pensate ad esso come una tabella hash, solo le chiavi di hash sono i nomi dei file ei valori associati sono i dati dei file.

Un collega ha detto di organizzarli in directory come questa: se voglio memorizzare un file denominato "foobar.txt" ed è memorizzato nell'unità D :, inserire il file in "D: \ f \ o \ o \ b \ a \ r. \ t \ x \ t". Non poteva spiegare perché questa era una buona idea però. C'è qualcosa per questa idea?

Qualche idea?

Il punto cruciale di questo è trovare un file. Qual è il modo più veloce per aprire un file per nome?

EDIT:

  • non ho alcun controllo sul file system su cui sono memorizzati i dati. Sarà NTFS o FAT32.
  • La memorizzazione dei dati di file in un database non è un'opzione.
  • I file saranno molto piccoli - massimo di probabilmente 1 kb.
  • Le unità stanno per essere allo stato solido.
  • L'accesso ai dati è praticamente casuale, ma probabilmente potrei calcolare una priorità per ogni file in base alla frequenza con cui viene richiesta. Alcuni file saranno accessibili molto più di altri.
  • Gli articoli verranno costantemente aggiunti e talvolta cancellati.
  • Non sarebbe pratico consolidare più file in file singoli perché non esiste un'associazione logica tra i file.
  • Mi piacerebbe raccogliere alcune metriche eseguendo test su questa roba, ma tale sforzo potrebbe diventare tanto impegnativo quanto il progetto stesso!
  • EDIT2:

    voglio upvote più risposte approfondite, se sono spot-on o no, e non possono a causa del mio status newbie. Scusate ragazzi!

    +0

    Questo dato è statico (750mil è esso) o si sta aggiungendo ad esso (aggiungere più file su base periodica)? Può essere letto solo o è necessario essere in grado di aggiornare i file? È veramente un accesso casuale ai file o ci sono dei tipi di accesso che potresti osservare a un'ispezione più ravvicinata? – Scanningcrew

    +0

    Domanda aggiornata per rispondere a questa domanda. (Più file aggiunti su base periodica, file cancellati in modo non raro. L'accesso è casuale, ma alcuni file saranno accessibili molto più di altri.) – JamesBrownIsDead

    +0

    Per il tuo commento EDIT2, hai solo bisogno di 15 rappresentanti per votare. Vedi http://stackoverflow.com/faq per i dettagli. –

    risposta

    0

    C'è qualche relazione tra i singoli file? Per quanto riguarda i tempi di accesso, le cartelle in cui vengono inserite le cose non influiranno molto; le posizioni fisiche sul disco sono ciò che importa.

    2

    Sembra che sarà in gran parte una questione di scelta del filesystem. Un'opzione da considerare potrebbe essere ZFS, è progettata per applicazioni ad alto volume.

    Si potrebbe anche voler considerare l'utilizzo di un database relazionale per questo genere di cose. 750 milioni di righe sono una sorta di database di medie dimensioni, quindi qualsiasi robusto DBMS (ad esempio PostgreSQL) sarebbe in grado di gestirlo bene. È possibile archiviare anche blob arbitrari nel database, quindi qualunque cosa stavi per archiviare nei file su disco puoi semplicemente archiviarli nel database stesso.

    Aggiornamento: Le tue informazioni aggiuntive sono certamente utili. Data una scelta tra FAT32 e NTFS, quindi sicuramente scegliere NTFS. Non memorizzare troppi file in una singola directory, 100.000 potrebbero essere un limite massimo da considerare (anche se dovrai sperimentare, non c'è una regola dura e veloce). Il suggerimento del tuo amico di una nuova directory per ogni lettera è probabilmente troppo, potresti prendere in considerazione la possibilità di scomporlo ogni quattro lettere o qualcosa del genere. Il miglior valore da scegliere dipende dalla forma del set di dati.

    Il motivo della rottura del nome è una buona idea è che in genere le prestazioni dei file system diminuiscono all'aumentare del numero di file in una directory. Questo dipende molto dal filesystem in uso, per esempio FAT32 sarà orribile con probabilmente solo poche migliaia di file per directory. Non vuoi spezzare i nomi dei file troppo, quindi ridurrai al minimo il numero di ricerche di directory che il filesystem dovrà fare.

    +0

    La soluzione di database funzionerà bene ma potrebbe non essere più veloce. Sarei molto cauto nell'indovinare senza prima fare alcuni test. Trovare un file tramite un indice DB significa utilizzare una struttura di ricerca. La soluzione suggerita di una implementazione trie basata su directory consente anche l'accesso a Olog (n) tramite un albero, ma suddividerlo in lettere significa che non si ha tanto controllo su come i nodi vengono suddivisi. I pattern nei nomi dei file potrebbero causare un enorme nodo. –

    +0

    Giusto, non tenterei di affermare che un database sarebbe più veloce, ma è un'altra opzione da prendere in considerazione. Tuttavia, i database sono progettati per gestire chiavi di tipo stringa con pattern patologici arbitrari. :) –

    0

    Perché non è possibile memorizzare i percorsi in una tabella di database accettabile?

    0

    Suppongo che stia pensando a una struttura dati Trie da creare sul disco in cui il nodo è una directory.

    1

    Questo dipende fortemente da molti fattori:

    • Quale sistema di file stai usando?
    • Quanto è grande ciascun file?
    • Che tipo di unità utilizzate?
    • Quali sono i modelli di accesso?

    L'accesso ai file a caso è molto costoso nei dischi tradizionali. Un miglioramento significativo che è possibile ottenere è l'utilizzo dell'unità a stato solido.

    Se è possibile ragionare su un modello di accesso, è possibile sfruttare la località di riferimento per posizionare questi file.

    Un altro modo possibile è utilizzare un sistema di database e archiviare questi file nel database per sfruttare il meccanismo di memorizzazione nella cache del sistema.

    Aggiornamento:

    Dato l'aggiornamento, è possbile consolidare alcuni file? I file 1k non sono molto efficienti da archiviare come file system (fat32, ntfs) hanno dimensioni del cluster e ogni file utilizzerà comunque le dimensioni del cluster anche se è più piccolo della dimensione del cluster. Di solito c'è un limite al numero di file in ogni cartella, con problemi di prestazioni. Puoi fare un semplice benchmark mettendo un massimo di 10k file in una cartella per vedere quanto le prestazioni peggiorano.

    Se si è impostato per utilizzare la struttura trie, suggerirei di esaminare la distribuzione dei nomi di file e quindi suddividerli in cartelle diverse in base alla distribuzione.

    1

    Ciò dipende in larga misura sulla quale sistema di file che si sta per memorizzare i file su. Le capacità dei file system nell'affrontare un numero elevato di file variano notevolmente.

    Il tuo collega suggerisce essenzialmente l'uso di un Trie data structure. L'uso di tale struttura di directory significherebbe che a ogni livello di directory ci sono solo una manciata di file/directory tra cui scegliere; questo può essere d'aiuto perché il numero di file all'interno di una directory aumenta il tempo di accesso a uno di essi (la differenza di orario effettiva dipende dal tipo di file system).

    Detto questo, personalmente non ne farei molti livelli profondi - tre o quattro livelli dovrebbero essere sufficienti per dare i benefici delle prestazioni - la maggior parte dei livelli dopo avrà probabilmente molte voci (supponendo che i nomi dei file non seguano particolari pattern.)

    Inoltre, vorrei memorizza il file stesso con il suo nome completo, questo renderà più semplice l'attraversamento manuale di questa struttura di directory, se necessario.

    Quindi, vorrei conservare foobar.txt come f/o/o/b/foobar.txt

    1

    Prima di tutto, la dimensione del file è molto piccolo. Qualsiasi file system mangerà qualcosa come almeno 4 volte più spazio. Voglio dire qualsiasi file sul disco occuperà 4kb per file 1kb. Soprattutto sui dischi SSD, il settore 4kb sarà la norma.

    Quindi è necessario raggruppare più file in 1 file fisico. Il file 1024 in 1 file di archiviazione sembra ragionevole. Per individuare i singoli file in questi file di archiviazione è necessario utilizzare alcuni RDBMS (PostgreSQL è stato menzionato ed è buono ma SQLite potrebbe essere più adatto a questo) o una struttura simile per eseguire la mappatura.

    La struttura di directory suggerita dal tuo amico suona bene ma non risolve il problema di archiviazione fisica. È possibile utilizzare una struttura di directory simile per archiviare i file di archiviazione. È meglio nominarli usando un sistema numerico.

    Se possibile, non lasciare che vengano formattati come FAT32, almeno NTFS o alcuni recenti file System di Unix. Poiché la dimensione totale dei file non è così grande, NTFS può essere sufficiente ma ZFS è l'opzione migliore ...

    2

    Questo algoritmo di file funzionerà, ma non è ottimale. Penserei che usare "segmenti" di 2 o 3 caratteri sarebbe meglio per le prestazioni, specialmente quando si inizia a prendere in considerazione l'esecuzione di backup.

    Ad esempio:
    d: \ storage \ fo \ ob \ ar \ foobar.txt
    o
    d: \ storage \ foo \ bar \ foobar.txt

    Ci sono alcuni vantaggi di utilizzare questo tipo di algoritmo:

    1. Nessun accesso al database è necessario.
    2. I file verranno distribuiti su più directory. Se non li diffondi, avrai gravi problemi di prestazioni. (Ricordo vagamente di aver sentito parlare di qualcuno che ha problemi a ~ 40.000 file in una singola cartella, ma non sono sicuro di quel numero.)
    3. Non è necessario cercare un file. È possibile capire esattamente dove un file sarà dal nome del file.
    4. Semplicità. Puoi facilmente portare questo algoritmo a qualsiasi lingua.

    ci sono alcuni aspetti negativi anche a questo:

    1. molti indici possono portare a rallentare i backup. Immagina di fare differenze ricorsive su queste directory.
    2. Scalabilità. Cosa succede quando si esaurisce lo spazio su disco e occorre aggiungere altro spazio di archiviazione?
    3. I nomi dei file non possono contenere spazi.
    0

    So che questo è un paio di anni di ritardo, ma forse questo può aiutare la persona accanto ..

    mio suggerimento utilizzare una SAN, mappato a un'unità Z che gli altri server possono mappare a pure. Non andrei con il percorso della cartella che il tuo amico ha detto di andare, ma più con un'unità: \ clientid \ anno \ mese \ giorno \ e se ingerisci più di 100.000 documenti al giorno, puoi aggiungere sottocartelle per ora e anche minuto se necessario. In questo modo, non hai mai più di 60 sottocartelle fino a secondi se necessario. Archiviare i collegamenti in SQL per il recupero e il reporting rapido. Ciò rende il percorso della cartella piuttosto breve, ad esempio: Z: \ 05 \ 2004 \ 02 \ 26 \ 09 \ 55 \ nomefile.txt in modo da non incorrere in alcuna limitazione 256 su tutta la linea.

    La speranza che aiuta qualcuno. :)