GNU/Linux >> Linux Esercitazione >  >> Linux

Non c'è davvero alcun blocco I/O asincrono su Linux?

(2020) Se stai usando un kernel Linux 5.1 o superiore puoi usare io_uring interfaccia per I/O simile a file e ottenere un eccellente funzionamento asincrono.

Rispetto al libaio esistente Interfaccia /KAIO, io_uring presenta i seguenti vantaggi:

  • Mantiene il comportamento asincrono quando si esegue l'I/O bufferizzato (e non solo quando si esegue l'I/O diretto)
  • Più facile da usare (soprattutto quando si usa il liburing libreria di supporto)
  • Opzionalmente può funzionare in modalità polling (ma avrai bisogno di privilegi più elevati per abilitare questa modalità)
  • Riduzione dello spazio di contabilità per I/O
  • Riduzione dell'overhead della CPU grazie a un minor numero di cambi di modalità syscall in spazio utente/kernel (un grosso problema di questi tempi a causa dell'impatto delle mitigazioni di spectre/meltdown)
  • I descrittori di file e i buffer possono essere preregistrati per risparmiare tempo di mappatura/annullamento della mappatura
  • Più veloce (può raggiungere un throughput aggregato più elevato, gli I/O hanno una latenza inferiore)
  • "Modalità collegata" può esprimere dipendenze tra I/O (>=kernel 5.3)
  • Può funzionare con I/O basato su socket (recvmsg() /sendmsg() sono supportati da>=5.3, vedi i messaggi che menzionano la parola support nella cronologia git di io_uring.c)
  • Supporta il tentativo di cancellazione dell'I/O in coda (>=5.5)
  • Può richiedere l'I/O sempre essere eseguito da un contesto asincrono piuttosto che dall'impostazione predefinita di ricorrere solo al puntare I/O a un contesto asincrono quando il percorso di invio inline attiva il blocco (>=5.6 kernel)
  • Crescente supporto per l'esecuzione di operazioni asincrone oltre read /write (ad es. fsync (>=5.1), fallocate (>=5.6), splice (>=5.7) e oltre)
  • Maggiore slancio di sviluppo
  • Non diventa bloccante ogni volta che le stelle non sono perfettamente allineate

Rispetto a POSIX AIO di glibc, io_uring presenta i seguenti vantaggi:

  • Molto più veloce ed efficiente (i vantaggi generali inferiori dall'alto si applicano ancora di più qui)
  • L'interfaccia è supportata dal kernel e NON utilizza un pool di thread in spazio utente
  • Quando si esegue l'I/O bufferizzato, vengono eseguite meno copie dei dati
  • Nessuna lotta con i segnali
  • L'AIO POSIX di Glibc non può avere più di un I/O attivo su un singolo descrittore di file mentre io_uring sicuramente sì!

Il documento Efficient IO con io_uring va molto più in dettaglio riguardo a io_uring vantaggi e utilizzo di . Il documento Cosa c'è di nuovo con io_uring descrive le nuove funzionalità aggiunte a io_uring tra i kernel 5.2 - 5.5, mentre l'articolo The rapid growth of io_uringLWN descrive quali funzionalità erano disponibili in ciascuno dei kernel 5.1 - 5.5 con uno sguardo in avanti a ciò che sarebbe stato in 5.6 (vedi anche l'elenco di articoli io_uring di LWN). C'è anche un IO più veloce attraverso la presentazione video (diapositive) delle ricette del kernel io_uring dalla fine del 2019 e la presentazione video (diapositive) delle ricette del kernel io_uring dalla metà del 2022 di io_uring. autore Jens Axboe. Infine, il tutorial Lord of the io_uring fornisce un'introduzione a io_uring utilizzo.

Il io_uring la community può essere raggiunta tramite la mailing list io_uring e gli archivi della mailing list io_uring mostrano il traffico giornaliero all'inizio del 2021.

Re "supporta l'I/O parziale nel senso di recv() rispetto a read() ":è stata inserita una patch nel kernel 5.3 che ritenterà automaticamente io_uring letture brevi e un ulteriore commit sono stati inseriti nel kernel 5.4 che modifica il comportamento in modo che si occupi automaticamente solo delle letture brevi quando si lavora con file "normali" su richieste che non hanno impostato REQ_F_NOWAIT flag (sembra che tu possa richiedere REQ_F_NOWAIT tramite IOCB_NOWAIT oppure aprendo il file con O_NONBLOCK ). Quindi puoi ottenere recv() style- comportamento I/O "breve" da io_uring anche.

Software/progetti che utilizzano io_uring

Sebbene l'interfaccia sia giovane (la sua prima incarnazione è arrivata a maggio 2019), alcuni software open source utilizzano io_uring "allo stato brado":

  • fio (anch'esso creato da Jens Axboe) ha un backend io_uring ioengine (infatti è stato introdotto in fio-3.13 da febbraio 2019!). La presentazione "Prestazioni di archiviazione migliorate utilizzando la presentazione SNIA della nuova interfaccia I/O del kernel Linux" (diapositive) di due ingegneri Intel afferma che sono stati in grado di ottenere il doppio degli IOPS su un carico di lavoro e meno della metà della latenza media a una profondità di coda di 1 su un altro carico di lavoro quando si confronta il io_uring ioengine al libaio ioengine su un dispositivo Optane.
  • Il progetto SPDK ha aggiunto il supporto per l'utilizzo di io_uring (!) per l'accesso ai dispositivi a blocchi nella sua versione v19.04 (ma ovviamente questo non è il backend che normalmente utilizzeresti SPDK per scopi diversi dal benchmarking). Più recentemente, sembra che abbiano anche aggiunto il supporto per l'utilizzo con i socket nella v20.04...
  • Ceph ha eseguito il commit di un backend io_uring a dicembre 2019 che faceva parte della versione 15.1.0. L'autore del commit ha pubblicato un commento su github che mostra che alcuni backend io_uring hanno alcuni vantaggi e svantaggi rispetto al backend libaio (in termini di IOPS, larghezza di banda e latenza) a seconda del carico di lavoro.
  • RocksDB ha commesso un io_uring backend per MultiRead nel dicembre 2019 e faceva parte della sua versione 6.7.3. Jens dichiara io_uring ha contribuito a ridurre drasticamente la latenza.
  • libev ha rilasciato la 4.31 con un io_uring iniziale backend nel dicembre 2019. Mentre alcuni dei punti originali dell'autore sono stati affrontati nei kernel più recenti, al momento della stesura (metà 2021) l'autore di libev ha alcune parole scelte su io_uring e sta adottando un approccio attendista prima di implementare ulteriori miglioramenti.
  • QEMU ha eseguito il commit di un backend io_uring nel gennaio 2020 e faceva parte del rilascio QEMU 5.0. Nella presentazione PDF "io_uring in QEMU:high-performance disk IO for Linux" Julia Suvorova mostra il io_uring back-end con prestazioni superiori a threads e aio backend su un carico di lavoro di 16K blocchi casuali.
  • Samba ha unito un io_uring Backend VFS nel febbraio 2020 e faceva parte della versione Samba 4.12. Nel "backend Linux io_uring VFS". Thread della mailing list di Samba, Stefan Metzmacher (l'autore del commit) dice il io_uring module è stato in grado di spingere circa il 19% in più di throughput (rispetto ad alcuni backend non specificati) in un test sintetico. Puoi anche leggere la presentazione PDF "Async VFS Future" di Stefan per alcune delle motivazioni alla base dei cambiamenti.
  • Il libunifex C++ sperimentale di Facebook lo usa (ma ti servirà anche un kernel 5.6+)
  • La gente della ruggine ha scritto involucri per creare io_uring più accessibile alla ruggine pura. rio è una libreria di cui si è parlato un po' e l'autore afferma di aver ottenuto un throughput più elevato rispetto all'utilizzo di chiamate di sincronizzazione racchiuse in thread. L'autore ha tenuto una presentazione del suo database e della sua libreria al FOSDEM 2020 che includeva una sezione che esaltava le virtù di io_uring .
  • La libreria di ruggine Glommio utilizza esclusivamente io_uring . L'autore (Glauber Costa) ha pubblicato un documento intitolato L'archiviazione moderna è molto veloce. Sono le API che sono pessime, dimostrando che con un'attenta messa a punto Glommio potrebbe ottenere prestazioni 2,5 volte superiori rispetto al normale (non-io_uring ) durante l'esecuzione di I/O sequenziali su un dispositivo Optane.
  • Gluster ha unito un io_uring posix xlator nell'ottobre 2020 e faceva parte della versione Gluster 9.0. L'autore del commit afferma che le prestazioni "non erano peggiori delle normali chiamate di sistema pwrite/pread".

Software che indaga utilizzando io_uring

  • Lo sviluppatore di PostgreSQL Andres Freund è stato una delle forze trainanti dietro io_uring miglioramenti (ad esempio la soluzione alternativa per ridurre la contesa di inode del filesystem). C'è una presentazione "Asynchronous IO for PostgreSQL" (tieni presente che il video è interrotto fino al segno dei 5 minuti) (PDF) che motiva la necessità di modifiche a PostgreSQL e dimostra alcuni risultati sperimentali. Ha espresso la speranza di ottenere il suo io_uring opzionale support in PostgreSQL 14 e sembra perfettamente consapevole di cosa funziona e cosa non funziona anche a livello di kernel. Nel dicembre 2020, Andres discute ulteriormente il suo PostgreSQL io_uring lavoro nel thread della mailing list pgsql-hackers "Blocking I/O, async I/O and io_uring" e menziona il lavoro in corso può essere visto su https://github.com/anarazel/postgres/tree/aio .
  • Il progetto Netty ha un repository incubatore che lavora su io_uring support che richiede un kernel 5.9
  • libuv ha una richiesta pull contro di esso aggiungendo io_uring support ma i suoi progressi nel progetto sono stati lenti
  • SwiftNIO ha aggiunto io_uring il supporto per gli eventi (ma non le chiamate di sistema) nell'aprile 2020 e il problema Linux:full io_uring I/O delinea i piani per integrarlo ulteriormente
  • Il progetto Tokio Rust ha sviluppato un proof of concept tokio-uring

Supporto distribuzione Linux per io_uring

  • (Fine 2020) L'ultimo kernel di abilitazione HWE di Ubuntu 18.04 è il 5.4 quindi io_uring è possibile utilizzare chiamate di sistema. Questa distribuzione non preconfeziona il liburing libreria helper ma puoi costruirla da solo.
  • Il kernel iniziale di Ubuntu 20.04 è 5.4 quindi io_uring è possibile utilizzare chiamate di sistema. Come sopra, la distribuzione non preconfeziona liburing .
  • Il kernel iniziale di Fedora 32 è 5.6 e ha un pacchetto liburing quindi io_uring è utilizzabile.
  • SLES 15 SP2 ha un kernel 5.3 quindi io_uring è possibile utilizzare chiamate di sistema. Questa distribuzione non preconfeziona il liburing libreria helper ma puoi costruirla da solo.
  • (metà 2021) Il kernel predefinito di RHEL 8 non supporta io_uring (una versione precedente di questa risposta diceva erroneamente di sì). C'è un articolo della knowledge base di Add io_uring support Red Hat (il contenuto è protetto da un paywall per gli abbonati) che è "in corso".
  • (metà 2022) Il kernel predefinito di RHEL 9 non supporta io_uring . Il kernel è abbastanza nuovo (5.14) ma supporta io_uring è esplicitamente disabilitato.

Si spera io_uring introdurrà una migliore storia di I/O asincrona simile a un file per Linux.

(Per aggiungere una sottile patina di credibilità a questa risposta, ad un certo punto in passato Jens Axboe (manutentore del livello di blocco del kernel Linux e inventore di io_uring ) ha pensato che valesse la pena votare questa risposta :-)


La vera risposta, puntata indirettamente da Peter Teoh, si basa su io_setup() e io_submit(). Nello specifico, le funzioni "aio_" indicate da Peter fanno parte dell'emulazione a livello utente di glibc basata sui thread, che non è un'implementazione efficiente. La vera risposta è in:

io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)

Si noti che la pagina man, datata 2012-08, afferma che questa implementazione non è ancora maturata al punto da poter sostituire l'emulazione dello spazio utente glibc:

http://man7.org/linux/man-pages/man7/aio.7.html

questa implementazione non è ancora maturata al punto in cui l'implementazione POSIXAIO può essere completamente reimplementata utilizzando le chiamate kernelsystem.

Quindi, secondo l'ultima documentazione del kernel che riesco a trovare, Linux non ha ancora un modello di I/O asincrono basato sul kernel maturo. E, se presumo che il modello documentato sia effettivamente maturo, non supporta ancora l'I/O parziale nel senso di recv() rispetto a read().


Linux
  1. Come si esegue l'I/O della console non bloccante su Linux in C?

  2. Come fermare il processo "ininterrotto" su Linux?

  3. C'è STDCALL in Linux?

  4. Come eliminare le cache di I/O su disco su Linux?

  5. Qual è l'equivalente Unix/Linux dell'I/O registrato?

10 Linux iostat Comando per segnalare la CPU e le statistiche di I/O

Report di I/O dalla riga di comando di Linux

Linux:come monitorare l'I/o del disco in una directory particolare?

10 esempi di iozone per la misurazione delle prestazioni di I/O del disco su Linux

Porte di completamento Linux e I/O?

Confusione sul meccanismo di I/O asincrono interno di node.js