Uso di O_DIRECT su Linux


23

Se questa domanda è troppo orientata al programmatore, fammi sapere. Mi chiedo se ci sono persone che hanno familiarità con il flag O_DIRECT per la chiamata di sistema open () su Linux 2.6? Linus disprezza il suo utilizzo, tuttavia la scrittura di file ad alte prestazioni sembra indicarne l'utilizzo. Mi piacerebbe conoscere qualsiasi esperienza e raccomandazioni del mondo reale.

Maggiori informazioni: L'applicazione che sto utilizzando non mantenere la propria cache, ed in tal modo raggiunge una media di 5 volte o più velocità in su. Quando si scrive su un file, il contenuto della cache deve essere scritto nella cache del filesystem, il che sembra ridondante e un problema di prestazioni.

Risposte:


17

Ok, chiedi esperienze, questo rende la domanda un po 'soggettiva e polemica, ma fattibile.

Linus ha detto che riferendosi agli usi che le persone di solito attribuiscono a O_DIRECT, e per questi usi, IMO Linus è per lo più corretto. Anche se si esegue l'I / O diretto, non è possibile trasferire i dati da / verso i dispositivi direttamente alle istruzioni del programma, è necessario un buffer riempito (dal programma o dal dispositivo) e trasferito attraverso una chiamata di sistema all'altra estremità. Inoltre, per renderlo efficiente, non vorrai rileggere qualcosa che hai già letto, nel caso ne avessi bisogno di nuovo. Quindi hai bisogno di una sorta di cache ... ed è esattamente quello che il kernel fornisce senza O_DIRECT, una cache di pagina! Perché non usarlo? Presenta anche vantaggi se più processi desiderano accedere allo stesso file contemporaneamente, sarebbe un disastro con O_DIRECT.

Detto questo, O_DIRECT ha i suoi usi: se per qualche motivo è necessario ottenere dati direttamente dal dispositivo a blocchi. Non ha nulla a che fare con le prestazioni.

Le persone che usano O_DIRECT per le prestazioni di solito provengono da sistemi con algoritmi di cache delle pagine errati, o senza meccanismi di consulenza POSIX, o persino persone che ripetono inconsapevolmente ciò che altre persone hanno detto. Per evitare questi problemi, O_DIRECT era una soluzione. Linux, OTOH, ha la filosofia secondo cui dovresti risolvere il vero problema di fondo, e il problema di fondo erano i SO che facevano un cattivo lavoro con la memorizzazione nella cache delle pagine.

Ho usato O_DIRECT per una semplice implementazione di cat per trovare un errore di memoria nella mia macchina. Questo è un uso valido per O_DIRECT. Non aveva nulla a che fare con le prestazioni.


Grazie per le informazioni, è apprezzato. Ho aggiornato la mia domanda con le condizioni specifiche dell'app che ha richiesto questa domanda. Se hai maggiori dettagli sui meccanismi di consulenza POSIX per la scrittura di file, anche questo sarebbe apprezzato.
casualunixer,

4
o_direct potrebbe anche essere utile in un sistema in cui lo sviluppatore desidera fornire un meccanismo di memorizzazione nella cache a livello dell'applicazione (think database).
Jmoney38,

Non ha nulla a che fare con le prestazioni. Questo non è sempre vero, specialmente per l'accesso a un dispositivo ad alta velocità in cui l'IO valuta la larghezza di banda della memoria in concorrenza, o anche solo una percentuale significativa della larghezza di banda della memoria. In tal caso, saltare la copia aggiuntiva nella / dalla cache della pagina può comportare vantaggi significativi in ​​termini di prestazioni.
Andrew Henle,

13

In realtà, O_DIRECT è necessario per evitare uno dei due

  • inquinamento della cache - a volte sai che non ha senso sovraccaricare la cache, ad esempio quando si tratta di file molto grandi, ad esempio 64 GiB quando ci sono solo 2 GiB di RAM. Il file Torrent di 32 GiB che un utente ha deciso di verificare non sembra essere un buon candidato per la memorizzazione nella cache. È solo attività extra con il suo overhead. E può causare l'eliminazione di alcuni dati davvero utili dalla cache.
  • doppia cache - ad esempio alcuni RDBMS (MySQL per citare) consente di definire la propria cache. I database presumibilmente sanno meglio come memorizzare nella cache e cosa, rispetto alla memoria virtuale del kernel che non sa nulla della pianificazione SQL e così via.

- che non va bene, come sembra. E O_DIRECTnon significa essere più veloci, spesso non lo è .


10
posix_fadvisepuò occuparsi del problema dell'inquinamento della cache.
psusi,

Non penso che la memoria virtuale abbia nulla a che fare con essa, si limita a mappare l'indirizzo di memoria. Buffer Cache / Page Cache è ciò che intendi.
ArekBulski,

La cache / cache è parte del sottosistema VM in UNIX, per quanto ne so, è per questo che ho usato questo termine. Grazie per la modifica. :)
poige,

6

Si noti che l'utilizzo O_DIRECTpotrebbe non riuscire nei kernel più recenti con i file system più recenti. Vedi questa segnalazione di bug per esempio. Quindi non solo l'uso è spesso discutibile, probabilmente non funzionerà affatto nella prossima generazione di distribuzioni Linux. Quindi non scommetterei sull'esecuzione del mio codice, anche se ti capita di essere in grado di dimostrare che potrebbe avere un vantaggio.


1
La segnalazione di bug in realtà discute l'uso dei filesystem con l'opzione journal = data attiva. Questa opzione è direttamente opposta in effetti al flag O_DIRECT. La maggior parte dei filesystem ext3 ed ext4 non hanno questo flag impostato e, in caso contrario, disattivarlo consentirà di aprire il file con O_DIRECT.
casualunixer,

3

Ha molto a che fare con le prestazioni.

Un esempio interessante è in mongodb che utilizza il motore mmap. O_DIRECT è meglio usato, come altri hanno affermato, dove è improbabile che i dati vengano letti per qualche tempo. In mongodb, il journal del database è scritto usando O_DIRECT mentre le scritture di dati e indici sono gestite dal meccanismo cache della pagina (pdflush) perché, sebbene O_DIRECT offra meno larghezza di banda, significa anche meno latenza e quindi riduce la perdita di dati in caso di interruzione imprevista (panico del kernel, errore del disco o dell'alimentazione). Si noti che è ancora presente il buffering prima che una scrittura O_DIRECT venga impegnata nella memorizzazione non volatile, ciò riduce solo la perdita di dati.

Un'altra caratteristica importante di O_DIRECT è che fornisce un maggiore controllo sulla sequenza di scritture. Ancora una volta non garantisce l'ordine delle scritture (a meno che non si disponga di un controller del disco di cache non volatile e non si stia utilizzando lo scheduler fifo, ma questi presentano le proprie complicazioni). Pertanto, sebbene mysql utilizzi O_DIRECT per i suoi dati / indici e per i suoi journal, può aspettarsi che quest'ultimo venga di solito impegnato per primo.

Ma è importante ricordare che O_DIRECT rompe l'equità nell'allocazione delle risorse. Uno dei motivi per cui l'applicazione viene accelerata è che sta rallentando altre cose.


Dici che ha molto a che fare con le prestazioni, ma fornisci un esempio in cui viene utilizzato per ridurre la latenza o le scritture degli ordini. Ma sono d'accordo che influisce sulle prestazioni. Punto giusto sull'equità.
ArekBulski,

Potete fornire più riferimenti che spiegano quando è ingiusto?
ACyclic,

3

In relazione a ciò che ha già detto @Juliano.

Verifica posix_fadvisese il vero problema è un comportamento errato dell'algoritmo cache del filesystem sottostante, puoi provare a dargli consigli, come hai intenzione di utilizzare il filesystem. Per i fs ben implementati, dovrebbe dare un aumento delle prestazioni. (Ecco il link ad un altro argomento che tocca considerazioni simili /programming//a/3755818/544721 )


1
Sembra che posix_fadvise cambi gli algoritmi readahead usati dal kernel. Il fattore critico con il codice nella domanda è la prestazione di scrittura. Il problema è che scrivere il buffer riempie prima le cache di Linux, che il kernel deve poi scaricare quando esaurisce la memoria. Questo è uno spreco di sforzi, in questo caso l'output dovrebbe essere minimamente bufferizzato sulla strada per il disco.
casualunixer
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.