Il modo migliore per memorizzare / recuperare milioni di file quando il loro meta-dati è in un database SQL

StackOverflow https://stackoverflow.com/questions/1257415

Domanda

Ho un processo che sta andando a generare inizialmente 3-4 milioni di file PDF, e continuare al ritmo di 80K / giorno. Saranno piuttosto piccole (50K) ciascuno, ma quello che mi preoccupa è come gestire la massa totale di file che sto generando per una facile ricerca. Alcuni dettagli:

  1. Io sono alcuni altri passaggi per eseguire una volta un file sono stati generati, e ci saranno un paio di server partecipanti, quindi avrò bisogno di guardare per i file man mano che vengono generate.
  2. Una volta generati, i file saranno disponibili anche se un processo di ricerca che ho scritto. In sostanza, avrò bisogno di tirare loro sulla base di un numero d'ordine, che è unico per ogni file.
  3. In qualsiasi momento, un numero d'ordine esistente può essere ripresentata, e il file generato sarà necessario sovrascrivere la copia originale.

In origine, avevo programmato di scrivere questi file tutto in una singola directory su un NAS, ma mi rendo conto che questo potrebbe non essere una buona idea, dato che ci sono milioni di loro e Windows potrebbe non gestire un milione di file-lookup molto con grazia. Sto cercando qualche consiglio:

  1. è una singola cartella va bene? non saranno mai essere incluso i file -. essi saranno recuperati solo con uno System.IO.File con un nome che ho già deciso
  2. Se faccio una cartella, posso guardare per i nuovi file con System.IO.DirectoryWatcher, anche con questo molti file, o si avvia a diventare pigro con che molti file?
  3. Dovrebbero essere memorizzati come BLOB in un database SQL Server, invece? Dal momento che avrò bisogno di recuperarli da un valore di riferimento, forse questo ha più senso.

Grazie per i vostri pensieri!

È stato utile?

Soluzione

avevo raggruppare i file in sottocartelle specifiche, e cercare di organizzarli (le sottocartelle) in qualche modo la logica business. Forse tutti i file realizzati durante un determinato giorno? Nel corso di un periodo di sei ore di ogni giorno? O ogni # dei file, direi un paio 1000 max. (C'è probabilmente un numero ideale là fuori, si spera che qualcuno sarà post-it.)

Fare i file mai invecchiano fuori e vengono eliminati? In tal caso, ordinare e file di essere pezzo cancellabile. In caso contrario, posso essere il fornitore dell'hardware?

C'è argomenti su entrambi i lati la memorizzazione dei file in un database.

  • Da un lato si ottiene una maggiore sicurezza, perche' è più difficile da estrarre i file dal DB; d'altra parte, si ottengono prestazioni potenzialmente più poveri, perche' è più difficile da estrarre i file dal DB.
  • Nel DB, non dovete preoccuparvi di come molti file per cartella, settore, gruppo NAS, qualunque sia - questo è il problema del DB, e probabilmente Hanno una buona implementazione per questo. Il rovescio della medaglia, sarà più difficile da gestire / rivedere i dati, in quanto sarebbe un blob bazillion in una singola tabella, e, beh, che schifo. (Si potrebbe dividere la tabella in base alla predetta business logica, il che renderebbe la cancellazione o l'archiviazione infinitamente più facile da eseguire. Che, o forse viste partizionate, dal momento che il partizionamento delle tabelle ha un limite di 1000 partizioni.)
  • SQL Server 2008 ha il tipo di dati FileStream; Non so molto su di esso, potrebbe essere merita di essere esaminata.

Un ultimo punto da preoccupare è mantenere i dati "allineato". Se il DB memorizza le informazioni sul file con il percorso / nome al file e il file viene spostato, si potrebbe ottenere totalmente hosed.

Altri suggerimenti

Per rispondere alle vostre domande:

  1. Non vorrei memorizzarli in una singola cartella. Come è probabile che ad un certo punto si consiglia di guardare i file effettivi sul disco, piuttosto che qualche altro modo.
    Invece perché non conservarli in directory separate, divise in lotti di 1000? Possibilmente utilizzando l'ID come chiave.
  2. che molti file probabilmente inondare il DirectorWatcher, in modo un po 'sarà perso. Ho usato questo in passato, e passato un certo punto (AFEW cento), ho trovato che inizia a perdere i file. Eventualmente utilizzare una directory diversa per i file in entrata, e quindi elaborare questo ogni tanto. Questo può quindi innescare un processo per aggiornare l'originale.
  3. Non sarebbe memorizzare i documenti in un database, ma sicuramente metadati in un database.

Si può facilmente organizzare i file in cartelle multiple, senza dover fare questo la logica di business, o un ordine-per-giorno, che è particolarmente bello se quel tipo di ordinamento sarebbe 'clumpy' (molti successi in una cartella, pochi in gli altri).

Il modo più semplice per farlo è quello di creare un hash univoco per il nome del file, in modo che forse si ottiene qualcosa di simile:

sf394fgr90rtfofrpo98tx.pdf

Poi rompere questo in blocchi di due caratteri, ed otterrete questo:

sf/39/4f/gr/90/rt/fo/fr/po/98/tx.pdf

Come si può vedere, ti dà una struttura di directory profonda che si può facilmente navigare.

Con una buona funzione di hash, questo sarà molto uniformemente distribuito, e non sarete mai ottenere più di 1296 voci per directory. Se mai una collisione (che dovrebbe essere estremamente raro), è sufficiente aggiungere un numero alla fine: tx.pdf, tx_1.pdf, tx_2.pdf. Anche in questo caso, le collisioni su tali grandi hash dovrebbe essere estremamente rara, in modo che il tipo di aggregazione che si ottiene a causa di questo sono un non-problema.

Hai detto che i documenti sono firmati digitalmente, quindi probabilmente si ha l'hash è necessario proprio lì sotto forma di stringa di firma.

1) Una cartella semplice può essere accettabilmente veloce con un indice separato, ma come è banale per metterlo nelle sottodirectory che permetterebbero te stesso la possibilità di navigare solo farlo.
Così ora si deve capire il tuo convenzione di denominazione. Anche se mi piacerebbe normalmente suggerisco un hash per ottenere una distribuzione uniforme di ID, ma come si sta facendo così tanto che probabilmente ha senso utilizzare i valori che hai già. Se hai un numero d'ordine avete un timestamp troppo? Se è così, basta anteporre il numero d'ordine con un timestamp.

Basta essere consapevoli che se si sta utilizzando gli ID di ordine è possibile riscontrare http: // it .wikipedia.org / wiki / Benford% 27s_law

È necessario testarlo. Tutte queste soluzioni dipendono dal file system sottostante. Alcuni file system in grado di gestire enormi directory, alcuni non possono. Alcuni indice di file system loro directory, alcuni non (questi due punti non sono necessariamente correlati).

rompere le cose fino a un albero di directory ha ragionevoli possibilità di essere performante, semplicemente perché, alla fine, le singole directory tendono ad avere poche entrate complessive. Che lavora per la maggior parte qualsiasi file system, semplicemente perché anche uno "stupido" che sta facendo una ricerca di directory lineare per il file può cercare un paio di centinaia di voci in tempi ragionevolmente rapidi.

Se il file system sta indicizzando le directory (come, ad esempio, un btree, o semplicemente l'ordinamento internamente che è effettivamente la stessa cosa in questo contesto), quindi le dimensioni di directory sono meno importanti, anche se alcuni strumenti possono lamentarsi (caricamento di un Esplora risorse di Windows finestra con i file di 4M, che sanno quello che accadrà).

Quindi, vorrei ricercare il sistema operativo previsto e le opzioni di filesystem, e testarlo e vedere quale funziona meglio per voi.

determinare alcune ordinamento logico delle sottodirectory e memorizzarli in blocchi di alcun file più di 512 o giù di lì in una cartella.

Non archiviare i file in un database. I database sono per i dati, i file server sono per i file. memorizzarli su un file server, ma memorizzare il percorso e il recupero delle informazioni in una banca dati.

Perché non considerando Memorizzazione di tutti quei file dopo essere stato convertito in PDF nel DB (blob) Quindi Vantaggi:

  1. I credere non dovrete fare direttamene con il sistema operativo di I / O, e lasciare tutto fino al DB.
  2. Non c'è bisogno di hash denominazione
  3. Facile per il backup e mantenere

Quando si utilizza un database per memorizzare i file, specialmente con file di piccole dimensioni l'overhead dovrebbe essere piccolo. ma si può anche fare cose come:

DELETE FROM BLOBTABLE WHERE NAME LIKE '<whatever>'

o quando si ha una data di scadenza, o desidera aggiornare un file, è rimuoverlo:

DELETE FROM BLOBTABLE WHERE CREATIONDATE < ...
etc...

Domanda:

Perché questi documenti devono essere generato e conservato in formato PDF?

Se possono essere generati, perché non solo conservare i dati nel database e li genera al volo quando richiesto? Ciò significa che è possibile cercare i dati effettivi che è richiesto per la ricerca in ogni caso e non avere i file su disco. In questo modo è possibile aggiornare il modello PDF quando richiesto, senza la necessità di rigenerare qualcosa?

1) Questo va totalmente in contrasto con quello che io predico in genere, ma si consiglia di memorizzarli in un database SQL dal momento che sono trully file di piccole dimensioni. SQL Server consentirebbe anche di trovare rapidamente e facilmente i file necessari senza trashing disco folle normalmente associati con l'enumerazione di una directory così grande. Inoltre, la memorizzazione dei file in SQL (mentre io sono in genere contro) sarebbe di grande facilità il backup / ripristino.

2) tutti Conservare in directory e sia loro indice con servizio di Windows indicizzazione ( brividi ) o creare il proprio indice in SQL Server che contiene il nome del file e percorso completo. Vorrei suggerire la loro memorizzazione in directory separate, con solo poche decine di migliaia di file ciascuno. Forse si potrebbe utilizzare l'anno ordine come il nome della cartella?

Indipendentemente da come la loro immagazzinata - non eseguire la scansione della directory per trovare i file -. Sarà sicuramente bisogno di avere un indice di qualche tipo

Spero che questo aiuti!

Il mio database file contiene oltre 4 milioni di cartelle, con molti file in ciascuna cartella.

Basta solo gettato tutte le cartelle in una directory. NTFS in grado di gestire questo senza alcun problema, e strumenti avanzati come robocopy possono aiutare quando è necessario spostarlo.

Basta fare in modo è possibile indicizzare i file senza una scansione. Ho fatto questo lanciando il mio indice in un database MySQL.

Quindi, per ottenere un file che cerco il database mysql su alcuni metadati e ottenere un indice. Poi io uso questo indice per leggere direttamente il file. Scaled bene per me finora. Ma nota che sarete girare tutto in accesso casuale e in lettura, quindi, casuale / scritture. Questo è scarso rendimento per HDD, ma per fortuna SSD aiuterà molto.

Inoltre, non vorrei tirare i file nel database mysql. Non sarà in grado di fare rete legge senza avere un client che capire mysql. In questo momento posso accedere a qualsiasi file attraverso la rete utilizzando qualsiasi programma, perché posso solo usare l'URL di rete.

Credo che come tanti altri hanno detto, si dovrebbe fare sottocartelle, ma in un modo che è possibile trovare i dati tramite il codice. Per esempio, se datetime funziona, usare quella. Da leggere quello che hai detto, sembrerebbe che ci sia una qualche forma di struttura gerarchica per i rapporti (giornaliera, settimanale, report giornaliero X, rapporto Y oraria, ecc) vorrei guardare la struttura di quando e perché i report vengono generati e costruire i miei directory in quel modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top