Memorizzare un milione di immagini nel filesystem


79

Ho un progetto che genererà un numero enorme di immagini. Circa 1.000.000 per iniziare. Non sono immagini di grandi dimensioni, quindi le memorizzerò tutte su una macchina all'avvio.

Come hai consigliato di archiviare queste immagini in modo efficiente? (File system NTFS attualmente)

Sto prendendo in considerazione uno schema di denominazione ... per iniziare tutte le immagini avranno un nome incrementale da 1 in su Spero che questo mi aiuterà a riordinarle in seguito, se necessario, e a buttarle in cartelle diverse.

quale sarebbe uno schema di denominazione migliore:

a / b / c / 0 ... z / z / z / 999

o

a / b / c / 000 ... z / z / z / 999

qualche idea su questo?


1
Sono legati a utenti specifici o semplicemente generici? Sono raggruppati in qualche modo?

solo generico. un mucchio di immagini generate da alcune attrezzature tecniche. li sto nominando incrementali da 1 in su solo per avere un'idea di un riferimento temporale.
s.mihai,

come verranno utilizzati / accessibili? tramite un'app su misura o cosa?
Colomba,


1
:)) sì ... 1 mil. immagini porno :))
s.mihai il

Risposte:


73

Consiglio di utilizzare un normale file system anziché i database. L'uso del file system è più semplice di un database, è possibile utilizzare strumenti normali per accedere ai file, i file system sono progettati per questo tipo di utilizzo, ecc. NTFS dovrebbe funzionare perfettamente come sistema di archiviazione.

Non memorizzare il percorso effettivo al database. Meglio memorizzare il numero di sequenza dell'immagine nel database e avere una funzione che può generare il percorso dal numero di sequenza. per esempio:

 File path = generatePathFromSequenceNumber(sequenceNumber);

È più facile da gestire se è necessario modificare in qualche modo la struttura delle directory. Forse hai bisogno di spostare le immagini in posizioni diverse, forse esaurisci lo spazio e inizi a memorizzare alcune delle immagini sul disco A e alcune sul disco B ecc. È più semplice cambiare una funzione che cambiare i percorsi nel database .

Vorrei usare questo tipo di algoritmo per generare la struttura delle directory:

  1. Il primo pad esegue il numero progressivo con zeri iniziali fino a quando non si dispone di almeno una stringa di 12 cifre. Questo è il nome per il tuo file. Potresti voler aggiungere un suffisso:
    • 12345 -> 000000012345.jpg
  2. Quindi dividere la stringa in 2 o 3 blocchi di caratteri in cui ogni blocco indica un livello di directory. Avere un numero fisso di livelli di directory (ad esempio 3):
    • 000000012345 -> 000/000/012
  3. Archivia il file nella directory generata:
    • Pertanto, il percorso completo e il nome file per il file con ID sequenza 123sono 000/000/012/00000000012345.jpg
    • Per il file con ID sequenza 12345678901234il percorso sarebbe123/456/789/12345678901234.jpg

Alcune cose da considerare sulle strutture delle directory e sull'archiviazione dei file:

  • L'algoritmo sopra ti dà un sistema in cui ogni directory foglia ha un massimo di 1000 file (se hai meno di 1 000 000 000 000 di file)
  • Potrebbero esserci dei limiti al numero di file e sottodirectory che una directory può contenere, ad esempio il file system ext3 su Linux ha un limite di 31998 sottodirectory per una directory.
  • Gli strumenti normali (WinZip, Esplora risorse, riga di comando, shell bash, ecc.) Potrebbero non funzionare molto bene se si dispone di un numero elevato di file per directory (> 1000)
  • La struttura della directory stessa occuperà un po 'di spazio su disco, quindi non vorrai troppe directory.
  • Con la struttura sopra puoi sempre trovare il percorso corretto per il file immagine semplicemente guardando il nome del file, se ti capita di rovinare le strutture della directory.
  • Se è necessario accedere ai file da più macchine, prendere in considerazione la condivisione dei file tramite un file system di rete.
  • La struttura di directory sopra non funzionerà se si eliminano molti file. Lascia "buchi" nella struttura delle directory. Ma dal momento che non stai eliminando alcun file, dovrebbe essere ok.

1
molto interessante! dividere il nome del file ... non ci avevo pensato. suppongo che questo sia il modo elegante di farlo: -?
s.mihai,

37
L'uso di un hash (come MD5) come nome del file, così come la distribuzione della directory, funzionerebbe. Non solo l'integrità dei file sarebbe un vantaggio collaterale allo schema di denominazione (facilmente controllabile), ma avrai una distribuzione ragionevolmente uniforme in tutta la gerarchia di directory. Quindi, se hai un file chiamato "f6a5b1236dbba1647257cc4646308326.jpg", lo memorizzeresti in "/ f / 6" (o nella profondità richiesta). 2 livelli di profondità forniscono 256 directory, o poco meno di 4000 file per directory per i file 1m iniziali. Sarebbe anche molto facile automatizzare la ridistribuzione a uno schema più profondo.

+1 Ho appena notato che questa risposta era simile a quella che ho appena pubblicato.
3dinfluence,

1
Sono assolutamente d'accordo sull'uso del sistema di file e sulla creazione di un identificatore artificiale per "suddividere" in nomi di cartelle. Ma dovresti anche provare a ottenere una distribuzione casuale di identificatori, cioè non usare un numero progressivo. Ciò ti consentirebbe di avere un albero di cartelle più bilanciato. Inoltre, con la distribuzione casuale è possibile partizionare più facilmente l'albero su più filesystem. Utilizzerei anche una SAN basata su ZFS con dedup attivato e un volume scarso per ciascun filesystem. È ancora possibile utilizzare NTFS utilizzando iSCSI per accedere alla SAN.
Michael Dillon,

Se si passa da destra a sinistra al passaggio 2, i file vengono distribuiti uniformemente. Inoltre non devi preoccuparti di non riempire con abbastanza zeri in quanto puoi un numero illimitato di file
ropo

31

Inserirò i miei 2 centesimi in un consiglio negativo: non andare con un database.

Lavoro con i database di memorizzazione delle immagini da anni: file di grandi dimensioni (1 meg-> 1 gig), spesso modificati, versioni multiple del file, a cui si accede ragionevolmente spesso. I problemi del database che si verificano con file di grandi dimensioni archiviati sono estremamente noiosi da affrontare, i problemi di scrittura e transazione sono complicati e si verificano problemi di blocco che possono causare gravi disastri ferroviari. Ho più pratica nello scrivere script dbcc e nel ripristinare tabelle dai backup di quanto dovrebbe mai fare una persona normale .

La maggior parte dei sistemi più recenti con cui ho lavorato hanno trasferito l'archiviazione dei file nel file system e si sono basati su database per nient'altro che indicizzazione. I file system sono progettati per sopportare questo tipo di abuso, sono molto più facili da espandere e raramente perdi l'intero file system se una voce viene danneggiata.


sì. nota presa!
s.mihai,

5
Hai esaminato il tipo di dati FILESTREAM di SQL 2008? È un incrocio tra database e archiviazione del file system.
NotMe

+1 sulla memorizzazione con il file server anziché un database mentre si eseguono operazioni di I / O veloci e poco frequenti.

Che cosa succede se si memorizzano solo poche centinaia di documenti o immagini per database - qualsiasi svantaggio nell'uso del database per l'archiviazione?
Bip bip

1
+1 ... un filesystem è in qualche modo un "database" (ntfs di sicuro), quindi perché renderlo eccessivamente complicato.
Akira,

12

Penso che la maggior parte dei siti che devono occuparsene utilizzino un hash di qualche tipo per assicurarsi che i file vengano distribuiti uniformemente nelle cartelle.

Quindi supponiamo di avere un hash di un file simile a questo. 515d7eab9c29349e0cde90381ee8f810
Potresti averlo memorizzato nella seguente posizione e puoi usare quanti livelli di profondità hai bisogno per mantenere basso il numero di file in ogni cartella.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Ho visto questo approccio preso molte volte. Hai ancora bisogno di un database per mappare questi hash di file su un nome leggibile e su tutti gli altri metadati che devi archiviare. Ma questo approccio si adatta abbastanza bene a b / c, puoi iniziare a distribuire lo spazio degli indirizzi hash tra più computer eo pool di archiviazione, ecc.


2
Git usa un approccio simile: git-scm.com/book/en/v2/Git-Internals-Git-Objects (per sostenere questa risposta)
aexl

11

Idealmente, è necessario eseguire alcuni test su tempi di accesso casuali per varie strutture, poiché la configurazione specifica del disco rigido, la memorizzazione nella cache, la memoria disponibile, ecc. Possono modificare questi risultati.

Supponendo che tu abbia il controllo sui nomi dei file, li partizionerei a livello di 1000 per directory. Più livelli di directory aggiungi, più inode masterizzi, quindi qui c'è un push-pull.

Per esempio,

/ Root / [0-99] / [0-99] / nome file

Nota: http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx contiene ulteriori dettagli sull'installazione di NTFS. In particolare, "Se si utilizza un numero elevato di file in una cartella NTFS (300.000 o più), disabilitare la generazione di nomi di file brevi per prestazioni migliori, e soprattutto se i primi sei caratteri dei nomi di file lunghi sono simili".

Dovresti anche cercare di disabilitare le funzionalità del filesystem che non ti servono (ad es. L'ora dell'ultimo accesso). http://www.pctools.com/guides/registry/detail/50/


3
+1 per disabilitare la generazione del nome file 8.3 e l'ora dell'ultimo accesso; quelle sono state le prime cose che mi sono venute in mente quando ho letto "un numero enorme di [file]" e "NTFS" (Windows).
ruba il

link in basso ........................
Pacerier,

7

Qualunque cosa tu faccia, non archiviarli tutti in una directory.

A seconda della distribuzione dei nomi di queste immagini, è possibile creare una struttura di directory in cui sono presenti cartelle di livello superiore a lettera singola in cui si avrebbe un altro set di sottocartelle per la seconda lettera di immagini ecc.

Così:

La cartella img\a\b\c\d\e\f\g\conterrebbe le immagini che iniziano con 'abcdefg' e così via.

È possibile introdurre la propria profondità appropriata richiesta.

La cosa grandiosa di questa soluzione è che la struttura delle directory agisce efficacemente come un dizionario / hash. Dato un nome di file di immagine, conoscerai la sua directory e una directory, conoscerai un sottoinsieme di immagini che vanno lì.


\ a \ b \ c \ d \ e \ f \ sto facendo ora, stavo pensando che ci sia un modo saggio per farlo.
s.mihai,

1
Questa è una soluzione generalmente accettata su come archiviarli fisicamente. La generazione chiara dell'URL dell'immagine è qualcosa che può essere facilmente eseguito in modo dinamico in base al nome del file immagine. Inoltre, per servirli, potresti persino introdurre sottodomini img-a, img-b sul server delle immagini, se lo desideri, per accelerare i tempi di caricamento.

2
E +1 per "non archiviarli tutti in una directory". Sto supportando un sistema legacy che ha inserito oltre 47000 file su un server in una singola cartella, e Explorer impiega circa un minuto per aprire la cartella.
Mark Ransom il

5
Fare un \ b \ c \ d \ e \ f \ g rende la struttura della directory molto profonda e ogni directory contiene solo pochi file. Meglio usare più di una lettera per livello di directory, ad es. Ab \ cd \ ef \ o abc \ def \. Le directory occupano anche spazio dal disco, quindi non ne vuoi troppe.
Juha Syrjälä,

2
Ho dovuto supportare un'applicazione che conteneva 4 + milioni di file in un'unica directory; ha funzionato sorprendentemente bene, ma non potresti MAI ottenere Explorer per aprire la cartella, ordinerebbe continuamente le nuove aggiunte. +1 per NTFS in grado di gestirlo senza morire.
SqlACID,

5

Vorrei memorizzarli sul file system ma dipende da quanto velocemente crescerà il numero di file. Questi file sono ospitati sul Web? Quanti utenti accederanno a questi file? Queste sono le domande a cui è necessario rispondere prima che io possa darti una migliore raccomandazione. Vorrei anche guardare Haystack da Facebook, hanno un'ottima soluzione per archiviare e servire immagini.

Inoltre, se si sceglie il file system, sarà necessario partizionare questi file con le directory. Ho esaminato questo problema e ho proposto una soluzione, ma non è assolutamente perfetta. Sto partizionando per hash table e gli utenti puoi leggere di più sul mio blog .


le immagini non sono pensate per un accesso frequente. quindi non c'è problema con questo. il loro numero crescerà abbastanza velocemente. suppongo che ci sarà il 1mil. segnare tra 1 mese.
s.mihai,

sono interessato al punto di vista del programmatore in modo da non pensare troppo a questo
s.mihai

Quindi, se non hai bisogno di un accesso veloce, Haystack probabilmente non fa per te. L'uso di Directories for Partitions è la soluzione più semplice a mio avviso.
Lukasz,

5

Abbiamo un sistema di archivio fotografico con 4 milioni di immagini. Utilizziamo il database solo per i metadati e tutte le immagini vengono archiviate nel file system utilizzando un sistema di denominazione inverso, in cui i nomi delle cartelle vengono generati dall'ultima cifra del file, dall'ultimo 1 e così via. ad es .: 000001234.jpg è memorizzato nella struttura di directory come 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Questo schema funziona molto bene con l'indice di identità nel database, perché riempie uniformemente l'intera struttura di directory.


4

Punto rapido, non è necessario memorizzare un percorso di file nel proprio DB. Puoi semplicemente memorizzare un valore numerico, se i tuoi file sono nominati nel modo che descrivi. Quindi, utilizzando uno degli schemi di archiviazione ben definiti già discussi, è possibile ottenere l'indice come numero e trovare molto rapidamente il file attraversando la struttura della directory.


: -? buon punto rapido. solo che ora non ho un algoritmo per generare il percorso.
s.mihai,


4

Le tue immagini dovranno essere nominate in modo univoco? Il processo che genera queste immagini può produrre lo stesso nome file più di una volta? Difficile dirlo senza sapere quale dispositivo sta creando il nome file, ma dire che il dispositivo è "ripristinato" e al riavvio inizia a denominare le immagini come ha fatto l'ultima volta che è stato "ripristinato" - se questo è un problema.

Inoltre, dici che colpirai 1 milione di immagini in un mese. Che ne dici dopo? Quanto velocemente queste immagini continueranno a riempire il file system? Arriveranno a un certo punto e livelleranno circa 1 milione di immagini TOTALI o continueranno a crescere e crescere, mese dopo mese?

Ti chiedo perché potresti iniziare a progettare il tuo file system per mese, quindi per immagine. Potrei essere propenso a suggerire di memorizzare le immagini in una tale struttura di directory:

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Il mese, l'anno e persino il giorno vanno bene per le immagini di sicurezza. Non sono sicuro se questo è quello che stai facendo, ma l'ho fatto con una videocamera di sicurezza domestica che scattava una foto ogni 10 secondi ... In questo modo la tua applicazione può eseguire il drill-down in un momento specifico o anche in un intervallo in cui potresti pensare che l'immagine sia stata generata . Oppure, anziché anno, mese - esiste qualche altro "significato" che può essere derivato dal file di immagine stesso? Alcuni altri descrittori, oltre all'esempio di data che ho dato?

Non memorizzerei i dati binari nel DB. Non ho mai avuto buone prestazioni / fortuna con quel genere di cose. Non posso immaginare che funzioni bene con 1 milione di immagini. Vorrei memorizzare il nome del file e basta. Se saranno tutti in JPG, non memorizzare nemmeno l'estensione. Vorrei creare una tabella di controllo che memorizzava un puntatore al server, all'unità, al percorso del file, ecc. In questo modo è possibile spostare quelle immagini in un'altra casella e comunque localizzarle. Hai bisogno di taggare le parole chiave con le parole? In tal caso, ti consigliamo di creare le tabelle appropriate che consentano quel tipo di tag.

Potresti aver affrontato queste idee mentre rispondevo .. Spero che questo aiuti ...


1.tutti i file saranno nominati in modo univoco 2.Il sistema crescerà e crescerà inizialmente uscirà intorno a 1 milione di immagini e poi crescerà ad una velocità di un paio di decine di migliaia al mese. 3. Ci sarà una sorta di tagging dei file ad un certo punto in futuro, ecco perché voglio archiviare una sorta di dati identificativi nel db.
s.mihai,

3

Sono coinvolto in un progetto che archivia 8,4 milioni di immagini nel corso di un anno per documentare lo stato di vari dispositivi. Le immagini più recenti sono accessibili più frequentemente e le immagini più vecchie vengono ricercate raramente a meno che non venga scoperta una condizione che ha spinto qualcuno a scavare negli archivi.

La mia soluzione, basata su questo utilizzo, era comprimere in modo incrementale le immagini in file compressi. Le immagini sono JPG, ciascuna di circa 20 kB e non comprimono molto, quindi lo schema di compressione ZIP è nessuno. Questo viene fatto semplicemente per concatenarli in una voce del filesystem che aiuta notevolmente NTFS in termini di velocità quando si tratta di spostarli da un disco all'altro o di consultare l'elenco dei file.

Le immagini più vecchie di un giorno vengono combinate in una zip "quotidiana"; le zip più vecchie di un mese vengono combinate nella rispettiva zip "mensile"; e, infine, non è più necessario nulla e, di conseguenza, più di un anno.

Questo sistema funziona bene perché gli utenti possono sfogliare i file (tramite il sistema operativo o un numero di applicazioni client) e tutto viene nominato in base ai nomi dei dispositivi e ai timestamp. Generalmente un utente conosce queste due informazioni e può individuare rapidamente uno qualsiasi dei milioni di immagini.

Capisco che questo probabilmente non è legato ai tuoi particolari dettagli, ma ho pensato di condividere.


2

Forse uno schema di denominazione basato sulla data di creazione - includendo tutte le informazioni nel nome del file o (meglio per navigare in seguito) suddividendolo in directory. Mi viene in mente quanto segue, a seconda della frequenza con cui generi le immagini:

  • Diverse immagini generate ogni giorno: Year/Month/Day/Hour_Minute_Second.png
  • Un paio al mese: Year/Month/Day_Hour_Minute_Second.png

ecc. Ottieni il mio punto ... =)


non vengono generati continuamente nel tempo, quindi alcune cartelle diventano grasse e altre rimangono ... sottili :))
s.mihai

Bene, ovviamente non devi creare ogni cartella, solo perché stai seguendo questo schema. Potresti anche avere Year/Month/Day/Hour/Minute- decidere di quanti livelli di cartelle hai bisogno in base alla frequenza con cui le immagini vengono generate quando il tasso è più alto - e quindi non creare cartelle che verrebbero lasciate vuote.
Tomas Aschan,

2

Sarei propenso a creare una struttura di cartelle basata sulla data, ad esempio \ anno \ mese \ giorno, e utilizzare i timestamp per i nomi dei file. Se necessario, i timestamp possono avere un componente contatore aggiuntivo se le immagini devono essere create così velocemente che potrebbe essercene più di una in un millisecondo. Utilizzando una sequenza dal più significativo al meno significativo per l'ordinamento dei nomi, la ricerca e la manutenzione sono un gioco da ragazzi. ad es. hhmmssmm [seq] .jpg


2

Stai considerando il ripristino di emergenza?

Alcune delle soluzioni proposte finiscono per alterare il nome del file (in modo tale che se il file fisico viene spostato, perdi la traccia di quale file sia realmente). Consiglio di mantenere un nome di file fisico univoco in modo che se l'elenco principale delle posizioni dei file viene danneggiato, è possibile rigenerarlo con una piccola shell, ehm, powershell, script;)

Da quello che ho letto qui sembra che tutti questi file sarebbero archiviati in un file system. Prendi in considerazione la possibilità di memorizzarli su più file system su più macchine. Se si dispone delle risorse, determinare un sistema di archiviazione di ciascun file su due macchine diverse nel caso in cui si perda un alimentatore e la sostituzione è di 2 giorni.

Considera quali tipi di procedure dovresti creare per migrare i file tra macchine o file system. La possibilità di farlo con il tuo sistema è attiva e online può farti risparmiare notevoli mal di testa lungo la strada.

È possibile considerare l'utilizzo di un GUID come nome di file fisico anziché come numero incrementale nel caso in cui il contatore dei numeri incrementali (la colonna dell'identità del database?) Venga incasinato.

Se appropriato, considera l'utilizzo di una CDN come Amazon S3.


2

Anche se non ho pubblicato immagini su quella scala, in precedenza ho scritto una piccola app per gallerie per servire immagini ~ 25k su una macchina a 400 MHz w. 512 MB di RAM circa. Alcune esperienze;

  • Evitare database di relazione a tutti i costi; mentre i database, senza dubbio, sono intelligenti nella gestione dei dati, non sono progettati per tale uso (abbiamo ottenuto database gerarchici di valori-chiave specializzati per quelli chiamati file system ). Anche se non ho altro che un sospetto, scommetterei che la cache del DB esce dalla finestra, se si lanciano BLOB davvero grandi. Mentre il mio hardware disponibile era in piccolo, non toccare affatto il DB nella ricerca delle immagini ha dato ordini di grandezza migliori velocità.

  • Ricerca come si comporta il file system; su ext3 (o era ext2 al momento - non ricordo), il limite di poter cercare in modo efficiente sottodirectory e file era intorno al segno 256; quindi avendo solo così tanti file e cartelle in una determinata cartella. Ancora una volta, notevole velocità. Sebbene non conosca NTFS, cose come XFS (che utilizza alberi B, per quanto mi ricordo) è estremamente veloce, semplicemente perché possono fare ricerche molto velocemente.

  • Distribuire i dati in modo uniforme; quando ho sperimentato quanto sopra, ho provato a distribuire i dati in modo uniforme su tutte le directory (ho fatto un MD5 dell'URL e l'ho usato per le directory; /1a/2b/1a2b...f.jpg). In questo modo ci vuole più tempo per raggiungere qualsiasi limite di prestazioni (e la cache del file system è comunque nulla in set di dati così grandi). (al contrario, potresti voler vedere in anticipo dove sono i limiti; quindi vuoi lanciare tutto nella prima directory disponibile.


2

Potrebbe essere in ritardo al gioco su questo. Ma una soluzione (se adatta al tuo caso d'uso) potrebbe essere l'hash del nome file. È un modo per creare un percorso di file facilmente riproducibile usando il nome del file creando allo stesso tempo una struttura di directory ben distribuita. Ad esempio, puoi usare i byte dell'hashcode del nome file come percorso:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Ciò comporterebbe che il percorso sia:

/172/029/cat.gif

È quindi possibile trovare cat.gifnella struttura delle directory riproducendo l'algoritmo.

Usare HEX come i nomi delle directory sarebbe facile come convertire i intvalori:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

Con il risultato di:

/AC/1D/cat.gif

Ho scritto un articolo su questo alcuni anni fa e recentemente l'ho spostato su Medium. Ha qualche dettaglio in più e un po 'di codice di esempio: Hashing del nome file: creazione di una struttura di directory con hash . Spero che sia di aiuto!


Conserviamo 1,8 miliardi di articoli usando qualcosa di simile. Funziona bene. Usa un hash veloce e con bassi tassi di collisioni e sei pronto.
CVVS


1

Se TUTTI non sono immediatamente necessari e puoi generarli al volo e queste sono piccole immagini, perché non implementare una memoria LRU o una cache del disco sopra il tuo generatore di immagini?

Questo potrebbe salvarti dalla memoria e mantenere le immagini calde da servire da mem?


1

Ho appena eseguito un test su zfs perché amo zfs e avevo una partizione da 500 gig su cui avevo la compressione. Ho scritto una sceneggiatura che ha generato file da 50 a 100.000 e li ha inseriti in directory nidificate 1/2/3/4/5/6/7/8 (5-8 livelli di profondità) e l'ho lasciato funzionare per 1 settimana. (Non è stato un ottimo script.) Ha riempito il disco e ha finito per avere circa 25 milioni di file o giù di lì. L'accesso a qualsiasi file con un percorso noto è stato immediato. Elencare qualsiasi directory con un percorso noto era istantaneo.

Tuttavia, ottenere un conteggio dell'elenco dei file (tramite find) ha richiesto 68 ore.

Ho anche eseguito un test mettendo molti file in una directory. Ho arrestato circa 3,7 milioni di file in una directory. L'elencazione della directory per ottenere un conteggio ha richiesto circa 5 minuti. L'eliminazione di tutti i file in quella directory ha richiesto 20 ore. Ma la ricerca e l'accesso a qualsiasi file sono stati immediati.


1

Vedo altro menzionare un database, ma non vedo menzione di questo nel tuo post. In ogni caso, la mia opinione su questo punto particolare è: attenersi a un database o a un file system. Se devi mescolare i due, stai attento. Le cose si complicano. Ma potresti doverlo fare. La memorizzazione di un milione di foto in un database non sembra la migliore idea.

Potresti essere interessato dalle seguenti specifiche, la maggior parte delle fotocamere digitali la seguono per gestire l'archiviazione dei file: https://en.wikipedia.org/wiki/Camera_Image_File_Format

In sostanza, viene creata una cartella, ad esempio 000OLYMPUSe le foto vengono aggiunte a quella cartella (ad esempio DSC0000.RAW). Quando il contatore del nome file raggiunge DSC9999.RAWuna nuova cartella viene creata ( 001OLYMPUS) e l'immagine viene aggiunta di nuovo, reimpostando il contatore, possibilmente con un prefisso diverso (es:) P_0000.RAW.

In alternativa puoi anche creare cartelle basate su parti del nome del file (già menzionato più volte). Ad esempio, se la tua foto è nominata IMG_A83743.JPG, salvala in IMG_\A8\3\IMG_A83743.JPG. È più complicato da implementare ma renderà i tuoi file più facili da trovare.

A seconda del filesystem (questo richiederà un po 'di ricerca), potresti essere in grado di scaricare tutte le immagini in una singola cartella, ma, nella mia esperienza, ciò di solito causerebbe problemi di prestazioni.


0

Potresti voler dare un'occhiata ai saluti ZFS (file system, volume manager di Sun)


0

Un modo chiaro per generare il percorso da un numero elevato è convertirlo facilmente in esadecimale e poi dividerlo!

per esempio 1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

Conservare e caricare:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

Codici sorgente completi: https://github.com/acrobit/AcroFS


-1

Sfortunatamente i filesystem sono pessimi (prestazioni con molti file per directory o alberi di directory profonde, controllo dei tempi al riavvio, affidabilità) nella gestione di molti file di piccole dimensioni, quindi la soluzione sopra che coinvolge i file ZIP è la cosa migliore se si desidera utilizzare un filesystem.

L'uso di un gestore di database è di gran lunga l'opzione migliore; uno semplice come BDB o GDBM per esempio; anche un DBMS relatrionale come MySQL sarebbe meglio. Solo le persone pigre che non capiscono i filesystem e i database (ad esempio quelli che rifiutano le transazioni) tendono ad usare i filesystem come database (o un po 'più raramente, viceversa).


-2

Che ne dite di un database con una tabella contenente un ID e un BLOB per memorizzare l'immagine? Quindi è possibile aggiungere nuove tabelle ogni volta che si desidera associare più elementi di dati a una foto.

Se ti aspetti di ridimensionare, perché non ridimensionare ora? Risparmierai tempo sia adesso che in seguito IMO. Implementa il livello del database una volta, che è abbastanza facile da iniziare. Oppure implementa qualcosa con cartelle e nomi di file e blah blah blah, e successivamente passa a qualcos'altro quando inizi a far esplodere MAX_PATH.


5
Sono stato lì, fatto quello, ho le cicatrici per dimostrarlo. I database che archiviano immagini in gran numero sono quasi irremovibili e richiedono quantità eccessive di manutenzione. Molto meglio archiviarli nel file system a meno che tu non abbia un'esigenza specifica a cui può rispondere solo un database (il nostro era il monitoraggio della versione.)
Satanicpuppy,

1
E ci sono molte utility per gestire file e file system, poche o nessuna per gestire i file all'interno di un database.
Mark Ransom,

2
Oh Dio No. Non utilizzare un database come archivio BLOB di grandi dimensioni.
Neil N,

Eek. Non sapevo che i database (ancora?) Hanno così tanti problemi con i BLOB.

Come può una soluzione così negativa che ha così tanti commenti avere ancora un +1? senza offesa per l'OP (vedo che proviene da SO) ma il pulsante downvote è qui per un motivo!
Mark Henderson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.