Quali sono le conseguenze sulle prestazioni di milioni di file in un moderno file system?


30

Supponiamo di utilizzare ext4 (con dir_index abilitato) per ospitare circa 3 milioni di file (con una dimensione media di 750 KB) e dobbiamo decidere quale schema di cartelle utilizzare.

Nella prima soluzione , applichiamo una funzione di hash al file e usiamo la cartella a due livelli (essendo 1 carattere per il primo livello e 2 caratteri al secondo livello): quindi essendo l' filex.forhash uguale a abcde1234 , lo memorizzeremo su / path / a / bc /abcde1234-filex.for.

Nella seconda soluzione , applichiamo una funzione di hash al file e usiamo la cartella a due livelli (essendo 2 caratteri per il primo livello e 2 caratteri al secondo livello): quindi essendo l' filex.forhash uguale a abcde1234 , lo memorizzeremo su / path / ab / de /abcde1234-filex.for.

Per la prima soluzione avremo il seguente schema /path/[16 folders]/[256 folders]con una media di 732 file per cartella (l'ultima cartella, dove risiederà il file).

Mentre sulla seconda soluzione avremo /path/[256 folders]/[256 folders]con una media di 45 file per cartella .

Considerando che scriveremo / scolleghiamo / leggiamo i file ( ma principalmente leggiamo ) da questo schema (fondamentalmente il sistema di cache nginx), maturerà, in senso prestazionale, se scegliamo una o l'altra soluzione?

Inoltre, quali sono gli strumenti che potremmo usare per controllare / testare questa configurazione?


7
Ovviamente il benchmarking aiuterà. Ma ext4 potrebbe essere il filesystem sbagliato per questo. Guarderei XFS.
ewwhite,

4
Non guarderei solo XFS, lo userei immediatamente senza ulteriori indugi. L'albero B + batte ogni volta la tabella hash.
Michael Hampton

Grazie per i suggerimenti, il benchmarking è un po 'difficile, ci ho provato, hdparm -Tt /dev/hdXma potrebbe non essere lo strumento più appropriato.
leandro moreira,

2
No hdparmnon è lo strumento giusto, è un controllo delle prestazioni non elaborate del dispositivo a blocchi e non un test del file system.
HBruijn,

Risposte:


28

Il motivo per cui si creerebbe questo tipo di struttura di directory è che i filesystem devono individuare un file all'interno di una directory, e più grande è la directory, più lenta sarà tale operazione.

Quanto più lentamente dipende dalla progettazione del filesystem.

Il filesystem ext4 utilizza un albero B per memorizzare le voci della directory. Una ricerca su questa tabella dovrebbe richiedere O (log n) tempo, che la maggior parte delle volte è inferiore alla tabella lineare ingenua utilizzata da ext3 e dai precedenti filesystem (e quando non lo è, la directory è troppo piccola per essere conta davvero).

Il filesystem XFS usa invece un albero B + . Il vantaggio di questo su una tabella hash o un albero B è che qualsiasi nodo può avere più figli b , dove in XFS b varia e può arrivare fino a 254 (o 19 per il nodo radice; e questi numeri potrebbero non essere aggiornati ). Questo ti dà una complessità temporale di O (log b n) , un grande miglioramento.

Entrambi questi filesystem possono gestire decine di migliaia di file in una singola directory, con XFS che è significativamente più veloce di ext4 in una directory con lo stesso numero di inode. Ma probabilmente non vuoi una singola directory con inode 3M, poiché anche con un albero B + la ricerca può richiedere del tempo. Questo è ciò che ha portato alla creazione di directory in questo modo, in primo luogo.

Per quanto riguarda le strutture proposte, la prima opzione che hai dato è esattamente ciò che viene mostrato negli esempi di nginx. Funzionerà bene su entrambi i filesystem, anche se XFS avrà ancora un piccolo vantaggio. La seconda opzione potrebbe avere prestazioni leggermente migliori o leggermente peggiori, ma probabilmente sarà abbastanza vicina, anche sui benchmark.


E per XFS o ext4, l'hardware su cui è installato il filesystem avrà un impatto enorme sulle prestazioni. Un'unità SATA da 5400 rpm lenta può eseguire circa 50 operazioni I / O casuali al secondo, una buona unità SAS da 15.000 rpm può fare alcune centinaia e un SSD sarà probabilmente limitato dalla larghezza di banda e potrebbe ottenere alcuni milioni di operazioni I / O casuali se non di più.
Andrew Henle,

1
A rigor di termini, $ O (\ log_b n) $ per $ b $ fisso ha la stessa complessità di $ O (\ log n) $. Ma per l'OP, le costanti effettive contano.
Hagen von Eitzen,

A meno che non ci sia qualcosa di sbagliato nel mio filesystem, ext4 non può gestire 10.000 file in una singola directory. Fare un semplice ls -lrichiede un minuto intero se la directory è caduta dalla cache dell'inode. E quando viene memorizzato nella cache, impiega ancora un secondo. Questo è con un SSD e un Xeon con tonnellate di RAM su un server web a traffico abbastanza basso.
Abhi Beckert,

@AbhiBeckert È stato aggiornato da ext3? In tal caso, prova a creare una nuova directory e sposta i file in essa.
Michael Hampton

@Hampton No. È un server (abbastanza) recentemente installato su hardware moderno. Ho lavorato sul problema con il nostro amministratore di sistema / data center per un paio di mesi. Stiamo pagando migliaia di dollari al mese per affittare il server e non ottenere prestazioni accettabili da esso. Sembra che l'unica opzione sia quella di passare a una nuova struttura di directory - forse usando gli hash invece delle date per i nomi dei file per distribuirli in modo più uniforme.
Abhi Beckert,

5

Nella mia esperienza, uno dei fattori di ridimensionamento è la dimensione degli inode data una strategia di partizionamento con nome hash.

Entrambe le opzioni proposte creano fino a tre voci di inode per ciascun file creato. Inoltre, 732 file creeranno un inode che è ancora inferiore ai soliti 16 KB. Per me, questo significa che entrambe le opzioni eseguiranno lo stesso.

Ti applaudo per il tuo hash corto; i sistemi precedenti su cui ho lavorato hanno preso lo sha1sum del file dato e le directory di giunzione basate su quella stringa, un problema molto più difficile.


1
Cosa rende l'uso delle somme SHA1 (e altre somme di hash più lunghe) "un problema molto più difficile"? È ingombrante per gli utenti umani, sì, ma è lo stesso per il sistema operativo, il file system e altri programmi.
Kbolino,

4

Certamente entrambe le opzioni aiuteranno a ridurre il numero di file in una directory a qualcosa che sembra ragionevole, per xfs o ext4 o qualunque altro file system. Non è ovvio quale sia meglio, dovrebbe testare per dire.

Il benchmark con la tua applicazione che simula qualcosa come il vero carico di lavoro è l'ideale. Altrimenti, inventati qualcosa che simuli in modo specifico molti piccoli file. A proposito, eccone uno open source chiamato smallfile . La sua documentazione fa riferimento ad altri strumenti.

hdparmfare I / O sostenuti non è così utile. Non mostrerà i molti piccoli I / O o voci di directory giganti associate a moltissimi file.


1

Uno dei problemi è il modo di scansionare la cartella.

Immagina il metodo Java che esegue la scansione sulla cartella.

Dovrà allocare una grande quantità di memoria e distribuirla in breve tempo, il che è molto pesante per la JVM.

Il modo migliore è di organizzare la struttura delle cartelle nel modo in cui ciascun file si trova nella cartella dedicata, ad esempio anno / mese / giorno.

Il modo in cui viene eseguita la scansione completa è che per ogni cartella esiste una corsa della funzione, quindi JVM uscirà dalla funzione, dislocerà la RAM ed eseguirà nuovamente su un'altra cartella.

Questo è solo un esempio, ma avere una cartella così grande non ha senso.


2
Stai assumendo Java e scansionando la cartella. Nessuno dei due è menzionato nella domanda, e ci sono altri modi per elaborare la cartella in Java oltre a scansionarla.
user207421

1

Ho avuto lo stesso problema. Cerca di archiviare milioni di file in un server Ubuntu in ext4. Ho finito con i miei benchmark. Ho scoperto che la directory flat funziona in modo molto migliore pur essendo molto più semplice da usare:

segno di riferimento

Ha scritto un articolo .


Questo non è sicuramente il risultato atteso. Prima di andare con questo o raccomandarlo, dovresti approfondire il motivo per cui hai ottenuto questo risultato inaspettato.
Michael Hampton
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.