Linux: quanti I / O su disco sono necessari per leggere un file? Come minimizzarlo? [duplicare]


10

Secondo questo articolo su Haystack di Facebook:

" A causa del modo in cui le appliance NAS gestiscono i metadati della directory, posizionare migliaia di file in una directory era estremamente inefficace in quanto la blockmap della directory era troppo grande per essere memorizzata nella cache in modo efficace dall'appliance. Di conseguenza era comune sostenere più di 10 operazioni su disco per recuperare un immagine singola Dopo aver ridotto le dimensioni della directory a centinaia di immagini per directory, il sistema risultante dovrebbe comunque sostenere 3 operazioni del disco per recuperare un'immagine: una per leggere i metadati della directory in memoria, una seconda per caricare l'inode in memoria e una terza per leggere il contenuto del file. "

Avevo supposto che i metadati e l'inode della directory del filesystem fossero sempre memorizzati nella RAM dal sistema operativo e una lettura del file avrebbe richiesto normalmente solo 1 I / O su disco.

Questo problema relativo a "I / O multipli su disco per leggere un singolo file" delineato in quel documento è univoco per i dispositivi NAS o Linux ha lo stesso problema?

Sto programmando di eseguire un server Linux per servire le immagini. In qualche modo posso ridurre al minimo il numero di I / O del disco - assicurandomi idealmente che il sistema operativo memorizzi nella cache tutti i dati di directory e inode nella RAM e che ogni lettura di file richiederebbe solo non più di 1 I / O su disco?


1
Non è una risposta alla domanda, ma puoi sempre usare Varnish (Facebook lo usa) che mantiene i file in memoria. In questo modo se un'immagine diventa calda (molte richieste allo stesso file), il disco IO non verrà utilizzato per servirlo

Darhazer - Varnish non aiuterebbe qui poiché la cache di file Linux (su cui Varnish fa affidamento) memorizza già nella cache i file caldi. Mettere Varnish davanti a Nginx per il servizio di file statici non aggiunge nulla. La mia domanda riguarda quando i file sono troppo grandi / troppi per essere memorizzati nella cache. Vorrei comunque assicurarmi che almeno i dati della directory e gli inode siano memorizzati nella cache per ridurre l'IO del disco a solo 1 per lettura.

Molti filesystem memorizzano l'inode all'interno della directory, riducendo di uno il numero di richieste e aumentando significativamente la possibilità di un hit nella cache. Ma questa non è una domanda di programmazione.
Ben Voigt,

È possibile modificare la dimensione del blocco del file system durante la creazione, ad esempio con il mke2fs -b 32768renderlo 32k. Tuttavia, questo è utile solo se non hai piccoli file su quel file system.

Risposte:


5

Linux ha lo stesso "problema". Ecco un mio articolo pubblicato due anni fa da uno studente, in cui l'effetto è mostrato su Linux. I vari IO possono provenire da diverse fonti:

  • Ricerca directory su ogni livello di directory del percorso del file. Potrebbe essere necessario leggere l'inode della directory e uno o più blocchi di immissione della directory
  • Inodo del file

Nel normale schema IO, la memorizzazione nella cache è davvero efficace e gli inode, le directory e i blocchi di dati sono allocati in modo da ridurre le ricerche. Tuttavia, il normale metodo di ricerca, che è effettivamente condiviso da tutti i file system, è dannoso per il traffico altamente randomizzato.

Ecco alcune idee:

1) La cache relativa al filesystem aiuta. Una cache di grandi dimensioni assorbirà la maggior parte delle letture. Tuttavia, se si desidera inserire più dischi in una macchina, il rapporto da disco a RAM limita la quantità di cache.

2) Non utilizzare milioni di piccoli file. Aggregali in file più grandi e memorizza il nome file e l'offset all'interno del file.

3) Posiziona o memorizza nella cache i metadati su un SSD.

4) E ovviamente usa un filesystem che non ha un formato di directory su disco totalmente anarchico. Un readdir non dovrebbe richiedere più di un tempo lineare e l'accesso diretto ai file idealmente solo un tempo logaritmico.

Mantenere piccole le directory (meno di 1000 o giù di lì) non dovrebbe essere di grande aiuto perché avresti bisogno di più directory con cui devi essere memorizzato nella cache.


E ovviamente usa un filesystem che non ha un formato di directory su disco totalmente arcaico. Un readdir non dovrebbe richiedere più di un tempo lineare e l'accesso diretto ai file idealmente solo un tempo logaritmico.
jørgensen,

Ho aggiunto che alla risposta come 4 ° punto
dmeister

@dmeister Roba buona. +1
Magellan,

@dmeister Il tuo link è morto.
Don Scott,

1

Questo dipende dal filesystem che intendi utilizzare. Prima di leggere il file system:

  • Leggi il file della directory.
  • Leggi l'inode del tuo file
  • Leggi i settori del tuo file

Se la cartella contiene un numero enorme di file, questa è una grande misura per la cache.


Se stai elencando gli accessi I / O, potrebbe essere più interessante separare quelli eseguiti da open()quelli eseguiti da read(). La pagina win.tue.nl/~aeb/linux/vfs/trail.html mostra una bella panoramica dei diversi concetti del kernel coinvolti. (Forse è obsoleto? Non sarei in grado di dirlo.)
adl

0

Probabilmente non sarai in grado di conservare tutti i dati di directory e inode nella RAM, poiché probabilmente hai più dati di directory e inode rispetto alla RAM. Potresti anche non volerlo, poiché quella RAM potrebbe essere utilizzata meglio per altri scopi; nel tuo esempio di immagine, non preferiresti avere i dati di un'immagine a cui si accede frequentemente nella cache nella RAM rispetto alla voce della directory per un'immagine a cui si accede raramente?

Detto questo, penso che la manopola vfs_cache_pressure sia usata per controllare questo. "Quando vfs_cache_pressure = 0, il kernel non reclamerà mai odontoiatria e inode a causa della pressione della memoria e questo può facilmente portare a condizioni di memoria insufficiente."

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.